Як отримати останній сегмент шляху URI


114

У мене є вхідна рядок, що є a URI. як можливо отримати останній відрізок шляху (що в моєму випадку є ідентифікатором)?

Це моя вхідна URL-адреса:

String uri = "http://base_path/some_segment/id"

і я повинен отримати ідентифікатор, який я спробував у цьому:

String strId = "http://base_path/some_segment/id";
strId = strId.replace(path);
strId = strId.replaceAll("/", "");
Integer id =  new Integer(strId);
return id.intValue();

але це не працює, і, безумовно, повинен бути кращий спосіб зробити це.

Відповіді:


174

це те, що ви шукаєте:

URI uri = new URI("http://example.com/foo/bar/42?param=true");
String path = uri.getPath();
String idStr = path.substring(path.lastIndexOf('/') + 1);
int id = Integer.parseInt(idStr);

альтернативно

URI uri = new URI("http://example.com/foo/bar/42?param=true");
String[] segments = uri.getPath().split("/");
String idStr = segments[segments.length-1];
int id = Integer.parseInt(idStr);

49
Я шукав android.net.Uri Android (не java.net.URI) і закінчив тут. Якщо ви використовуєте це замість цього, існує метод, який називається getLastPathSegment (), який повинен робити те саме. :)
— pm_labs

5
Так само String idStr = new File(uri.getPath()).getName(), як і ця відповідь, але використовує Fileзамість того, Stringщоб розділити шлях.
— Джейсон C

це звичайна робота для URL-адрес, наприклад example.com/job/senior-health-and-nutrition-advisor/?param=true . Останній "/" створює проблеми. Вам потрібна якась більш добра відповідь getLastPathSegment (), надана @paul_sns.
— Вайбхав Кадам

@VaibhavKadam добре, технічно ви можете стверджувати, що останній сегмент - порожній рядок. Але якщо це не те, що ви хочете, просто використовуйте:while (path.endsWith("/")) path = path.substring(0, path.length() - 1);
— sfussenegger

@sfussenegger Моє погано, що я не читав теги, про які йдеться. Я думав, що в ньому є тег Android. Ну +1 для android.net.uri. :). Android переймає JAVA.
— Вайбхав Кадам

69
import android.net.Uri;
Uri uri = Uri.parse("http://example.com/foo/bar/42?param=true");
String token = uri.getLastPathSegment();

1
Це "android.net.Uri"? База набирає теги питання, ява.net.URI буде припущено, і у неї немає getLastPathSegment () ...
— Майкл Гейзер

Крім того, Uriназва класу Android є малим і не може бути використана. Я виправив вашу відповідь, використовуючи статичний заводський метод Uri.parse().
— тихість

Тут не існує GetLastPathSegment.
— Абдулла Шойб

2
у нього є getLastPathSegment (), але він не працює! повертає нуль!
— Junia Montana

Здається, що getLastPathSegment () випадковим чином виплющує для мене повний шлях.
— MobDev

48

Ось короткий спосіб зробити це:

public static String getLastBitFromUrl(final String url){
    // return url.replaceFirst("[^?]*/(.*?)(?:\\?.*)","$1);" <-- incorrect
    return url.replaceFirst(".*/([^/?]+).*", "$1");
}

Код тесту:

public static void main(final String[] args){
    System.out.println(getLastBitFromUrl(
        "http://example.com/foo/bar/42?param=true"));
    System.out.println(getLastBitFromUrl("http://example.com/foo"));
    System.out.println(getLastBitFromUrl("http://example.com/bar/"));
}

Вихід:

42
фут-
бар

Пояснення:

.*/      // find anything up to the last / character
([^/?]+) // find (and capture) all following characters up to the next / or ?
         // the + makes sure that at least 1 character is matched
.*       // find all following characters


$1       // this variable references the saved second group from above
         // I.e. the entire string is replaces with just the portion
         // captured by the parentheses above

в той час як я є великим шанувальником регексу і сам його часто використовую, я визнаю, що для більшості розробників, регулярний генекс є настільки ж тупим, як це стає. це не простіше у тому, що це не швидко зрозуміти.
— Білл Тернер

Клас /"заперечувані символи" [^/?]зайвий, тому що він ніколи не буде відповідати. .*/завжди буде відповідати останній / у рядку, тому жодного іншого /не слід зустріти.
— Стефан ван ден Аккер

не працює для такого роду посилань. http://example.com/foo#reply2Буде чудово, якщо ви зможете оновити свою відповідь, щоб вирішити її. Спасибі
— Сет

23

Я знаю, що це старе, але рішення тут здаються досить багатослівними. Просто легко читається один вкладиш , якщо у вас є URLабо URI:

String filename = new File(url.getPath()).getName();

Або якщо у вас є String:

String filename = new File(new URL(url).getPath()).getName();

Чи працює це з усіма можливими параметрами URL-адреси, наприклад a.co/last?a=1#frag. Я думаю , що немає, так як код не робить подстроки останнього символу шляху до кінця: path.substring(index + 1).
— АлікЕльзін-кілака

4
@alik Питання задає останній відрізок шляху. Запит та фрагмент не є частиною сегменту шляху.
— Джейсон C

13

Якщо ви використовуєте Java 8 і хочете останній сегмент у шляху до файлу, який ви можете зробити.

Path path = Paths.get("example/path/to/file");
String lastSegment = path.getFileName().toString();

Якщо у вас є такий URL, який http://base_path/some_segment/idви можете зробити.

final Path urlPath = Paths.get("http://base_path/some_segment/id");
final Path lastSegment = urlPath.getName(urlPath.getNameCount() - 1);

4
Ризиково, тому що java.nio.file.Paths # get залежить від файлової системи ОС, на якій працює JVM. Немає гарантій, що він розпізнає URI з пересічними прямими як роздільники шляху.
— Адріан Бейкер

2
Що з URI з парами запитів? Трактування випадкового URI як шляху до файлової системи вимагає виключення.
— Абхіджіт Саркар

9

В Android

Android має вбудований клас для управління URI.

Uri uri = Uri.parse("http://base_path/some_segment/id");
String lastPathSegment = uri.getLastPathSegment()

Іноді це просто виплює повний шлях. Не впевнений, чому або коли це здається випадковим.
— MobDev

Якщо ви можете вловити вміст, який він аналізує, можливо, ви можете встановити тест одиниці, щоб переконатися.
— Брілл Паппін

8

У Java 7+ декілька попередніх відповідей можна об'єднати, щоб дозволити отримати будь-який сегмент шляху з URI, а не лише останній сегмент. Ми можемо перетворити URI в java.nio.file.Pathоб’єкт, щоб скористатися його getName(int)методом.

На жаль, статична фабрика Paths.get(uri)не побудована для обробки схеми http, тому спочатку нам потрібно відокремити схему від шляху URI.

URI uri = URI.create("http://base_path/some_segment/id");
Path path = Paths.get(uri.getPath());
String last = path.getFileName().toString();
String secondToLast = path.getName(path.getNameCount() - 2).toString();

Щоб отримати останній сегмент в одному рядку коду, просто вкладіть рядки вище.

Paths.get(URI.create("http://base_path/some_segment/id").getPath()).getFileName().toString()

Щоб отримати сегмент "другий-останній", уникаючи номерів індексу та потенціалу помилок "один за одним", використовуйте getParent()метод.

String secondToLast = path.getParent().getFileName().toString();

Зверніть увагу, що getParent()метод може бути викликаний повторно для отримання сегментів у зворотному порядку. У цьому прикладі шлях містить лише два сегменти, інакше виклик getParent().getParent()отримає сегмент третій-останній.


6

Якщо ви commons-ioвключили у свій проект, ви можете це зробити, не створюючи непотрібних об’єктів за допомогоюorg.apache.commons.io.FilenameUtils

String uri = "http://base_path/some_segment/id";
String fileName = FilenameUtils.getName(uri);
System.out.println(fileName);

Дасть вам останню частину шляху, яка є id


3

Ви можете використовувати getPathSegments()функцію. ( Документація на Android )

Розглянемо свій приклад URI:

String uri = "http://base_path/some_segment/id"

Останній сегмент можна отримати за допомогою:

List<String> pathSegments = uri.getPathSegments();
String lastSegment = pathSegments.get(pathSegments.size - 1);

lastSegmentбуде id.


1

Ви також можете використовувати substituAll:

String uri = "http://base_path/some_segment/id"
String lastSegment = uri.replaceAll(".*/", "")

System.out.println(lastSegment);

результат:

id

0

Я використовую наступне у класі корисності:

public static String lastNUriPathPartsOf(final String uri, final int n, final String... ellipsis)
  throws URISyntaxException {
    return lastNUriPathPartsOf(new URI(uri), n, ellipsis);
}

public static String lastNUriPathPartsOf(final URI uri, final int n, final String... ellipsis) {
    return uri.toString().contains("/")
        ? (ellipsis.length == 0 ? "..." : ellipsis[0])
          + uri.toString().substring(StringUtils.lastOrdinalIndexOf(uri.toString(), "/", n))
        : uri.toString();
}

-1

Отримайте URL-адресу від URI і використовуйте getFile (), якщо ви не готові використовувати підстроковий спосіб вилучення файлу.


2
не буде працювати, див. javadoc з getFile (): Отримує ім'я файлу цієї URL-адреси. Повернута частина файлу буде такою ж, як getPath (), плюс об'єднання значення getQuery (), якщо така є. Якщо немає частини запиту, цей метод і getPath () повернуть однакові результати.)
— sfussenegger

Використовуйте getPath()не getFile().
— Джейсон C
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.