Як отримати останній сегмент шляху 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.