2011-05-05 17 views
16

提取參數在Java中,我有:如何從一個給定的URL

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

我想要得到的depCity參數(PAR,NYC)的值。

因此,我創建的正則表達式:

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

m.find()是返回false。 m.groups()正在返回IllegalArgumentException

我在做什麼錯?

+0

的可能的複製[解析URI字符串到名稱 - 值集合(https://stackoverflow.com/questions/13592236/parse-a-uri-string-into-name-value-collection) – 2017-11-17 13:52:30

回答

39

它不一定是正則表達式。因爲我覺得有來處理這件事情沒有標準的方法,我用的東西,我從什麼地方抄(也許是修改了一下):

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

所以,當你調用它,你會得到所有的參數和他們的價值。該方法處理多值參數,因此List<String>而不是String,在你的情況下,你需要獲得第一個列表元素。

+0

這個解決方案也在工作,但是我個人並不喜歡Google地圖 - 我嘗試使用更簡單的解決方案。不過謝謝! – gospodin 2011-05-06 08:36:46

+8

地圖是一個非常核心和簡單的概念,所以我沒有看到他們的問題。 – Bozho 2011-05-06 08:38:04

+3

此解決方案不考慮在「#」之後末尾附加的URL的片段部分。在http url中,這部分引用了一個內部的錨點。因此,變量查詢必須在「#」處再次拆分,然後必須進一步處理返回數組的索引0。 – haferblues 2012-10-31 08:56:23

13

不知道你怎麼用了findgroup,但能正常工作:

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 
} 

但是,如果你只希望值,而不是關鍵depCity=那麼您可以使用m.group(1)或者使用與lookarounds正則表達式:

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

它在與上面相同的Java代碼中工作。它試圖在depCity=之後立即找到起始位置。然後儘可能少地匹配任何東西,直到達到面向&或輸入結束的點。

+0

這種情況完美!謝謝 – gospodin 2011-05-06 08:35:40

+1

只是一個小小的評論:而不是使用複雜的模式「(?<= depCity =)。*?(?=&| $)」來獲得唯一的值,Im使用第一個soluiton「depCity =([^&] + )「與m.group(1)結合使用以獲取僅值。 – gospodin 2011-05-06 08:55:48

5

我有三個解決方案,第三個是Bozho的改進版本。

首先,如果你不想自己寫的東西,簡單地用一個lib,然後使用Apache的httpcomponents LIB的URIBuilder類: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; 
} 

二:

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's的改進版」?這是一個褻瀆。 :) – Zeemee 2014-10-14 09:06:10

7

如果您正在開發Android應用程序,請嘗試以下操作:

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'類的什麼庫? – 2016-12-15 10:40:15

+0

import android.net.Uri; – 2016-12-16 11:29:12

2

簡單的解決方案創建所有參數名稱和值的地圖,並使用它:)。

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

提示:'添加字符串參數= URLDecoder.decode(param,「UTF-8」);'內部循環 – Marckaraujo 2017-02-13 13:19:54

1

如果彈簧的web存在於類路徑,UriComponentsBuilder都可以使用。

MultiValueMap<String, String> queryParams = 
      UriComponentsBuilder.fromUriString(url).build().getQueryParams();