Cara mendapatkan segmen jalur terakhir dari sebuah URI

114

Saya memiliki sebagai masukan string yaitu a URI. bagaimana mungkin untuk mendapatkan segmen jalur terakhir (yang dalam kasus saya adalah id)?

Ini adalah URL masukan saya:

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

dan saya harus mendapatkan id yang telah saya coba dengan ini:

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

tetapi tidak berhasil, dan pasti ada cara yang lebih baik untuk melakukannya.

DX89B
sumber

Jawaban:

174

apakah itu yang kamu cari:

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);

kalau tidak

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);
sfussenegger.dll
sumber
49
Saya mencari android.net.Uri Android (bukan java.net.URI) dan berakhir di sini. Jika Anda menggunakannya, ada metode di sana yang disebut getLastPathSegment () yang harus melakukan hal yang sama. :)
pm_labs
5
Lakukan saja String idStr = new File(uri.getPath()).getName(), sama seperti jawaban ini tetapi menggunakan Filealih-alih Stringmembagi jalan.
Jason C
ini tidak akan berfungsi untuk url seperti example.com/job/senior-health-and-nutrition-advisor/?param=true . "/" Terakhir membuat masalah. Butuh sesuatu yang lebih bagus, jawaban getLastPathSegment () yang diberikan oleh @paul_sns sempurna.
Vaibhav Kadam
@VaibhavKadam baiklah, secara teknis Anda bisa membantah bahwa segmen terakhir adalah string kosong. Tetapi jika bukan itu yang Anda inginkan, cukup gunakan:while (path.endsWith("/")) path = path.substring(0, path.length() - 1);
sfussenegger
@sfussenegger Maaf, saya tidak membaca TAG yang dipermasalahkan. Saya pikir itu memiliki tag android. Baik +1 untuk android.net.uri. :). Android mengambil alih JAWA.
Vaibhav Kadam
69
import android.net.Uri;
Uri uri = Uri.parse("http://example.com/foo/bar/42?param=true");
String token = uri.getLastPathSegment();
Tambahan
sumber
1
Apakah ini "android.net.Uri"? Basis don tag pertanyaan, java.net.URI akan diasumsikan dan tidak memiliki getLastPathSegment () ...
Michael Geiser
Selain itu, Urinama kelas Android adalah huruf kecil dan tidak dapat dibuat instance-nya. Saya telah mengoreksi jawaban Anda untuk menggunakan metode pabrik statis Uri.parse().
quietmint
GetLastPathSegment tidak ada di sini.
Abdullah Shoaib
2
itu memang memiliki getLastPathSegment () tetapi tidak berhasil! mengembalikan nol!
Junia Montana
Sepertinya getLastPathSegment () secara acak memberikan jalur lengkap untuk saya.
MobDev
48

Berikut metode singkat untuk melakukannya:

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

Kode Tes:

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/"));
}

Keluaran:

42
foo
bar

Penjelasan:

.*/      // 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
Sean Patrick Floyd
sumber
Meskipun saya adalah penggemar berat regex dan sering menggunakannya sendiri, saya menyadari bahwa bagi sebagian besar pengembang, regex sama bodohnya dengan yang didapat. tidak lebih sederhana dalam kenyataan bahwa hal itu tidak segera dipahami.
Bill Turner
The /di kelas karakter menegasikan [^/?]tidak perlu, karena tidak akan pernah cocok. .*/akan selalu cocok dengan yang terakhir / di String, jadi tidak ada yang lain yang /harus ditemui.
Stefan van den Akker
tidak berfungsi untuk tautan semacam ini http://example.com/foo#reply2, Alangkah baiknya jika Anda dapat memperbarui jawaban Anda untuk menyelesaikannya. Terima kasih
Seth
23

Saya tahu ini sudah lama, tetapi solusi di sini tampaknya agak bertele-tele. Hanya satu baris yang mudah dibaca jika Anda memiliki URLatau URI:

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

Atau jika Anda memiliki String:

String filename = new File(new URL(url).getPath()).getName();
Jason C
sumber
Apakah itu berfungsi dengan semua kemungkinan opsi URL, seperti a.co/last?a=1#frag. Saya pikir tidak, karena kode tidak substring dari simbol jalan terakhir sampai akhir: path.substring(index + 1).
AlikElzin-kilaka
4
@alik Pertanyaan menanyakan segmen jalur terakhir. Kueri dan fragmen bukan bagian dari segmen jalur.
Jason C
13

Jika Anda menggunakan Java 8 dan Anda ingin segmen terakhir di jalur file, Anda dapat melakukannya.

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

Jika Anda memiliki url seperti yang http://base_path/some_segment/idAnda bisa lakukan.

final Path urlPath = Paths.get("http://base_path/some_segment/id");
final Path lastSegment = urlPath.getName(urlPath.getNameCount() - 1);
Will Humphreys
sumber
4
Berisiko karena java.nio.file.Paths # get bergantung pada sistem file OS tempat JVM dijalankan. Tidak ada jaminan itu akan mengenali URI dengan garis miring ke depan sebagai pemisah jalur.
Adrian Baker
2
Bagaimana dengan URI dengan parameter kueri? Memperlakukan URI acak sebagai jalur sistem file akan meminta pengecualian.
Abhijit Sarkar
9

Di Android

Android memiliki kelas bawaan untuk mengelola URI.

Uri uri = Uri.parse("http://base_path/some_segment/id");
String lastPathSegment = uri.getLastPathSegment()
Brill Pappin
sumber
Terkadang ini hanya menunjukkan jalan penuh. Tidak yakin mengapa atau kapan tampaknya acak.
MobDev
Jika Anda dapat menangkap konten yang diurai, mungkin Anda dapat menyiapkan pengujian unit untuk memastikannya.
Brill Pappin
8

Di Java 7+, beberapa jawaban sebelumnya dapat digabungkan untuk memungkinkan pengambilan segmen jalur apa pun dari URI, bukan hanya segmen terakhir. Kita bisa mengonversi URI menjadi java.nio.file.Pathobjek, untuk memanfaatkan getName(int)metodenya.

Sayangnya, pabrik statis Paths.get(uri)tidak dibangun untuk menangani skema http, jadi pertama-tama kita perlu memisahkan skema dari jalur 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();

Untuk mendapatkan segmen terakhir dalam satu baris kode, cukup tambahkan baris di atas.

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

Untuk mendapatkan segmen kedua hingga terakhir sambil menghindari nomor indeks dan potensi kesalahan off-by-one, gunakan getParent()metode ini.

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

Perhatikan bahwa getParent()metode ini dapat dipanggil berulang kali untuk mengambil segmen dalam urutan terbalik. Dalam contoh ini, jalur hanya berisi dua segmen, jika tidak, pemanggilan getParent().getParent()akan mengambil segmen ketiga hingga terakhir.

jaco0646
sumber
6

Jika Anda telah commons-iomemasukkan dalam proyek Anda, Anda dapat melakukannya tanpa membuat objek yang tidak perlu denganorg.apache.commons.io.FilenameUtils

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

Akan memberi Anda bagian terakhir dari jalan, yaitu id

Bnrdo
sumber
3

Anda dapat menggunakan getPathSegments()fungsi. ( Dokumentasi Android )

Pertimbangkan contoh URI Anda:

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

Anda bisa mendapatkan segmen terakhir menggunakan:

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

lastSegmentakan menjadi id.

Sina Masnadi
sumber
1

Anda juga dapat menggunakan replaceAll:

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

System.out.println(lastSegment);

hasil:

id
Krzysztof Cichocki
sumber
0

Saya menggunakan yang berikut ini di kelas utilitas:

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();
}
Gerold Broser
sumber
-1

Dapatkan URL dari URI dan gunakan getFile () jika Anda belum siap menggunakan cara substring untuk mengekstrak file.

Nageswara Rao
sumber
2
tidak akan berfungsi, lihat javadoc dari getFile (): Mendapatkan nama file dari URL ini. Porsi file yang dikembalikan akan sama dengan getPath (), ditambah penggabungan nilai getQuery (), jika ada. Jika tidak ada bagian kueri, metode ini dan getPath () akan mengembalikan hasil yang identik.)
sfussenegger
Gunakan getPath()tidak getFile().
Jason C