Bir URI'nin son yol segmenti nasıl elde edilir


114

Giriş olarak bir URI. son yol parçasını (benim durumumda bu bir id) nasıl elde edilebilir?

Bu benim girdi URL'm:

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

ve bununla denediğim kimliği almam gerekiyor:

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

ama işe yaramıyor ve kesinlikle bunu yapmanın daha iyi bir yolu olmalı.

Yanıtlar:


174

Aradığın şey bu mu:

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

alternatif olarak

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'in android.net.Uri'sini (java.net.URI değil) arıyordum ve buraya geldim. Bunun yerine bunu kullanıyorsanız, aynı şeyi yapması gereken getLastPathSegment () adında bir yöntem vardır. :)
pm_labs

5
Sadece String idStr = new File(uri.getPath()).getName()bu cevapla aynı yapın, ancak yolu bölmek Fileyerine kullanır String.
Jason C

bu, example.com/job/senior-health-and-nutrition-advisor/?param=true gibi url'ler için işe yaramayacaktır . Son "/" sorun çıkarıyor. Daha iyi bir şeye ihtiyacınız var getLastPathSegment () @paul_sns tarafından verilen cevap mükemmeldir.
Vaibhav Kadam

@VaibhavKadam iyi, teknik olarak son segmentin boş bir dize olduğunu iddia edebilirsiniz. Ama eğer istediğiniz bu değilse, basitçe kullanın:while (path.endsWith("/")) path = path.substring(0, path.length() - 1);
sfussenegger

@sfussenegger Benim hatam söz konusu TAG'leri okumadım. Android etiketi olduğunu sanıyordum. Android.net.uri için iyi +1. :). Android, JAVA'yı devralıyor.
Vaibhav Kadam

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

1
Bu "android.net.Uri" mi? Sorunun etiketlerini temel alın, java.net.URI varsayılır ve bir getLastPathSegment () yok ...
Michael Geiser

Ayrıca, Android Urisınıf adı küçük harflidir ve somutlaştırılamaz. Statik fabrika yöntemini kullanmak için cevabınızı düzelttim Uri.parse().
quietmint

GetLastPathSegment burada mevcut değil.
Abdullah Shoaib

2
getLastPathSegment () var ama çalışmıyor! boş döndürür!
Junia Montana

Görünüşe göre getLastPathSegment () benim için tam yolu rastgele ortaya koyuyor.
MobDev

48

İşte bunu yapmanın kısa bir yöntemi:

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

Test Kodu:

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

Çıktı:

42
foo
çubuğu

Açıklama:

.*/      // 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

Ben düzenli ifadenin büyük bir hayranıyım ve bunu sık sık kendim kullansam da, çoğu geliştirici için normal ifadenin olabildiğince geniş olduğunu biliyorum. hızlı bir şekilde anlaşılmadığı için daha basit değildir.
Bill Turner

/Negatif karakter sınıfında [^/?]bu eşleştirilecek asla, çünkü gereksizdir. .*/her zaman String'deki son / ile eşleşir , bu nedenle başka hiçbir /şeye rastlanmamalıdır.
Stefan van den Akker

bu tür bir bağlantı için çalışmaz http://example.com/foo#reply2, cevabınızı çözmek için güncellemeniz harika olur. Teşekkürler
Seth

23

Bunun eski olduğunu biliyorum, ancak buradaki çözümler oldukça ayrıntılı görünüyor. Bir URLveya varsa, kolayca okunabilen tek satırlık bir kalem URI:

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

Veya eğer varsa String:

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

Bu sanki bir URL tüm olası seçenekleri ile çalışmak mu a.co/last?a=1#frag. Kod sonuna kadar geçen yol sembolünün alt dize gelmez gibi ben değil düşünüyorum: path.substring(index + 1).
AlikElzin-kilaka

4
@alik Soru, son yol parçasını soruyor. Sorgu ve parça, yol segmentinin parçası değildir.
Jason C

13

Java 8 kullanıyorsanız ve bir dosya yolundaki son kesimi istiyorsanız bunu yapabilirsiniz.

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

http://base_path/some_segment/idYapabileceğiniz gibi bir url'niz varsa.

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

4
Riskli çünkü java.nio.file.Paths # get, JVM'nin üzerinde çalıştığı işletim sistemi dosya sistemine bağlıdır. Yol ayırıcıları olarak eğik çizgi içeren bir URI'yi tanıyacağının garantisi yoktur.
Adrian Baker

2
Sorgu parametreli URI ne olacak? Rastgele bir URI'yi bir dosya sistemi yolu olarak ele almak bir istisna gerektiriyor.
Abhijit Sarkar

9

Android'de

Android, URI'leri yönetmek için yerleşik bir sınıfa sahiptir.

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

Bazen bu, tüm yolu ortaya çıkarır. Neden veya ne zaman rastgele göründüğünden emin değilim.
MobDev

Ayrıştırdığı içeriği yakalayabilirseniz, emin olmak için bir birim testi kurabilirsiniz.
Brill Pappin

8

Java 7 + 'da, önceki yanıtlardan birkaçı, yalnızca son segment yerine bir URI'den herhangi bir yol segmentinin alınmasına izin vermek için birleştirilebilir . Yönteminden java.nio.file.Pathyararlanmak için URI'yi bir nesneye dönüştürebiliriz getName(int).

Maalesef, statik fabrika Paths.get(uri)http şemasını işleyecek şekilde oluşturulmamıştır, bu nedenle ilk önce şemayı URI'nin yolundan ayırmamız gerekir.

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

Son segmenti bir kod satırında elde etmek için yukarıdaki satırları iç içe geçirmeniz yeterlidir.

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

Endeks numaralarından ve olası bir hata olasılığından kaçınırken ikinciden son segmenti elde etmek için getParent()yöntemi kullanın .

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

getParent()Yöntemin, segmentleri ters sırada almak için tekrar tekrar çağrılabileceğini unutmayın . Bu örnekte, yol yalnızca iki parça içerir, aksi takdirde arama getParent().getParent(), üçüncüden son parçaya kadar alır.


6

Eğer varsa commons-ioprojeniz dahil, sizinle gereksiz nesneleri yaratmadan bunu yapabilirorg.apache.commons.io.FilenameUtils

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

Size yolun son bölümünü verecek id


3

getPathSegments()İşlevi kullanabilirsiniz . ( Android Belgeleri )

Örnek URI'nizi düşünün:

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

Son segmenti kullanarak elde edebilirsiniz:

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

lastSegmentolacak id.


1

Ayrıca replaceAll'ı da kullanabilirsiniz:

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

System.out.println(lastSegment);

sonuç:

id

0

Bir yardımcı program sınıfında aşağıdakileri kullanıyorum:

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

URI'den URL alın ve dosya ayıklamak için alt dize yöntemini kullanmaya hazır değilseniz getFile () kullanın.


2
çalışmaz, bkz. getFile () javadoc'u: Bu URL'nin dosya adını alır. Döndürülen dosya kısmı getPath () ile aynı olacaktır, artı varsa getQuery () değerinin birleşimi olacaktır. Sorgu bölümü yoksa, bu yöntem ve getPath () aynı sonuçları döndürecektir.)
sfussenegger

Kullanım getPath()değil getFile().
Jason C
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.