2011-05-05 20 views
16

parametreleri ayıklamak için nasıl vardır:Java'da belirli bir url

String params = "depCity=PAR&roomType=D&depCity=NYC"; 

ben depCity parametreleri (PAR, NYC) değerlerini almak istiyorum.

String regex = "depCity=([^&]+)"; 
Pattern p = Pattern.compile(regex); 
Matcher m = p.matcher(params); 

m.find() yanlış döndürüyor:

Yani normal ifade yarattı. m.groups(), IllegalArgumentException döndürüyor.

Neyi yanlış yapıyorum?

+0

Olası kopyalar (https://stackoverflow.com/questions/13592236/parse-a-uri-string-into-name-value-collection) –

cevap

39

Düzenli olması gerekmez.

public static Map<String, List<String>> getQueryParams(String url) { 
    try { 
     Map<String, List<String>> params = new HashMap<String, List<String>>(); 
     String[] urlParts = url.split("\\?"); 
     if (urlParts.length > 1) { 
      String query = urlParts[1]; 
      for (String param : query.split("&")) { 
       String[] pair = param.split("="); 
       String key = URLDecoder.decode(pair[0], "UTF-8"); 
       String value = ""; 
       if (pair.length > 1) { 
        value = URLDecoder.decode(pair[1], "UTF-8"); 
       } 

       List<String> values = params.get(key); 
       if (values == null) { 
        values = new ArrayList<String>(); 
        params.put(key, values); 
       } 
       values.add(value); 
      } 
     } 

     return params; 
    } catch (UnsupportedEncodingException ex) { 
     throw new AssertionError(ex); 
    } 
} 

Yani onu çağırdığınızda, tüm parametreleri almak ve olacaktır: Bu şeyi işlemek için standart bir yöntem olduğunu düşünüyorum, ben bir yere kopyalanmış bir şey kullanıyorum (ve belki biraz değiştirilmiş) onların değerleri. Yöntem, çok değerli paramları, dolayısıyla String yerine List<String>'u işler ve sizin durumunuzda ilk liste öğesini almanız gerekir.

+0

Bu çözüm de çalışıyor, ama ben şahsen ben bir Haritalar hayranı değilim - Ben daha basit çözümler kullanmayı deneyin. Yinede teşekkürler! – gospodin

+8

Haritalar çok temel ve basit bir kavramdır, bu yüzden onlarla ilgili bir sorun görmüyorum. – Bozho

+3

Bu çözüm, bir "#" sonrasındaki sonuna eklenen bir URL parçasını dikkate almaz. Http URL'lerinde bu kısım bir dahili bağlantıya işaret eder. Bu yüzden değişken sorgu tekrar "#" olarak bölünmeli ve sonra döndürülen dizinin 0 'ı daha fazla işlenmelidir. – haferblues

13

Eğer find ve group, kullanılan ancak bu gayet iyi çalışıyor nasıl emin değil:

String params = "depCity=PAR&roomType=D&depCity=NYC"; 

try { 
    Pattern p = Pattern.compile("depCity=([^&]+)"); 
    Matcher m = p.matcher(params); 
    while (m.find()) { 
     System.out.println(m.group()); 
    } 
} catch (PatternSyntaxException ex) { 
    // error handling 
} 

Ancak, yalnızca değerleri değil, anahtar depCity= o zaman m.group(1) kullanabilir veya lookarounds ile normal ifadeler kullanabilirsiniz ya istiyorsanız :

Pattern p = Pattern.compile("(?<=depCity=).*?(?=&|$)"); 

Yukarıdaki gibi aynı Java kodunda çalışır. depCity='dan hemen sonra bir başlangıç ​​konumu bulmaya çalışır. Ardından, & veya girişin sonuna bakan bir noktaya ulaşıncaya kadar mümkün olan en az şeyle eşleşir.

+0

gibi köşe durumları için bir ArrayIndexOutOfBoundException artacak Bu mükemmel çalışıyor! teşekkürler – gospodin

+1

Sadece küçük bir açıklama: karmaşık model kullanmak yerine "(? <= depCity =). *? (? = & | $)" sadece değerleri almak için, ilk çözelti kullanıyorum "depCity = ([^ &] +) "sadece değerleri almak için m.group (1) ile birlikte. – gospodin

5

Üç çözümüm var, üçüncüsü Bozho'nun geliştirilmiş bir versiyonudur. İkinci http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/client/utils/URIBuilder.html

new URIBuilder("http://...").getQueryParams()... 

:

// overwrites duplicates 
import org.apache.http.NameValuePair; 
import org.apache.http.client.utils.URLEncodedUtils; 
public static Map<String, String> readParamsIntoMap(String url, String charset) throws URISyntaxException { 
    Map<String, String> params = new HashMap<>(); 

    List<NameValuePair> result = URLEncodedUtils.parse(new URI(url), charset); 

    for (NameValuePair nvp : result) { 
     params.put(nvp.getName(), nvp.getValue()); 
    } 

    return params; 
} 

İkincisi: Eğer şeyler kendiniz yazmak istiyorum ve sadece bir lib kullanın yoksa

Birincisi, daha sonra Apache HttpComponents lib en URIBuilder sınıfını kullanın

public static Map<String, List<String>> getQueryParams(String url) throws UnsupportedEncodingException { 
    Map<String, List<String>> params = new HashMap<String, List<String>>(); 
    String[] urlParts = url.split("\\?"); 
    if (urlParts.length < 2) { 
     return params; 
    } 

    String query = urlParts[1]; 
    for (String param : query.split("&")) { 
     String[] pair = param.split("="); 
     String key = URLDecoder.decode(pair[0], "UTF-8"); 
     String value = ""; 
     if (pair.length > 1) { 
      value = URLDecoder.decode(pair[1], "UTF-8"); 
     } 

     // skip ?& and && 
     if ("".equals(key) && pair.length == 1) { 
      continue; 
     } 

     List<String> values = params.get(key); 
     if (values == null) { 
      values = new ArrayList<String>(); 
      params.put(key, values); 
     } 
     values.add(value); 
    } 

    return params; 
} 
+0

"Bozho'nun geliştirilmiş versiyonu"? Bu bir kutsallık. :) – Zeemee

7

Android uygulaması geliştiriyorsanız, şunu deneyin:

String yourParam = null; 
Uri uri = Uri.parse(url); 
     try { 
      yourParam = URLDecoder.decode(uri.getQueryParameter(PARAM_NAME), "UTF-8"); 
     } catch (UnsupportedEncodingException exception) { 
      exception.printStackTrace(); 
     } 
+0

Uri sınıfı için hangi kütüphaneyi kullanıyorsunuz? –

+0

import android.net.Uri; –

2

Basit Çözüm Tüm param ad ve değerlerini haritadan oluşturun ve kullanın :). yay ağ üzerinde sınıf mevcut ise

import org.apache.commons.lang3.StringUtils; 

    public String splitURL(String url, String parameter){ 
       HashMap<String, String> urlMap=new HashMap<String, String>(); 
       String queryString=StringUtils.substringAfter(url,"?"); 
       for(String param : queryString.split("&")){ 
        urlMap.put(StringUtils.substringBefore(param, "="),StringUtils.substringAfter(param, "=")); 
       } 
       return urlMap.get(parameter); 
      } 
+0

İpucu: 'Dize ekle param = URLDecoder.decode (param," UTF-8 ");' iç döngü – Marckaraujo

1

, UriComponentsBuilder kullanılabilir.

MultiValueMap<String, String> queryParams = 
      UriComponentsBuilder.fromUriString(url).build().getQueryParams(); 
[Ad-Değer Koleksiyonu içine URI dize ayrıştırma] arasında
İlgili konular