2011-05-05 3 views
16

에서 매개 변수를 추출하는 방법이있다 :자바에서는 해당 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

가능한 복제 (https://stackoverflow.com/questions/13592236/parse-a-uri-string-into-name-value-collection) –

답변

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

그래서, 당신이 그것을 호출 할 때, 당신은 모든 매개 변수를 얻을 것이다 :이 일을 처리하는 표준 방법이 없다 생각 때문에, 내가 어딘가에서 복사 한 것을 사용하고 있습니다 (아마도 약간 수정) 그들의 가치. 이 메서드는 복수 값 매개 변수를 처리하므로 String 대신 List<String>이되며, 첫 번째 목록 요소를 가져와야합니다.

+0

이 솔루션도 작동하지만 개인적으로지도의 팬이 아닙니다. 더 간단한 솔루션을 사용하려고합니다. 어쨌든 고마워! – gospodin

+8

지도는 매우 핵심적이고 간단한 개념이므로 문제는 없습니다. – Bozho

+3

이 해결 방법은 끝에 "#"다음에 추가되는 URL의 조각 부분을 고려하지 않습니다. http urls에서이 부분은 내부 앵커를 참조합니다. 그래서 가변 쿼리는 "#"에서 다시 나눠 져야하고 리턴 된 배열의 인덱스 0은 더 처리되어야합니다. – haferblues

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

+1

그냥 작은 말 : 대신 복잡한 패턴을 사용하여 "(? <= depCity =).? (? = | $가) *"유일한 값을 얻을 수있는 첫 번째 soluiton "을 사용하여 임 depCity = ([^ &] +) "를 m.group (1)과 조합하여 값만 가져옵니다. – gospodin

5

세 가지 솔루션이 있습니다. 세 번째는 개선 된 버전의 Bozho입니다. 둘째 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; 
} 

둘째, 당신이 물건을 직접 작성하려면 단순히 lib 디렉토리를 사용하지 않는 경우

첫째, 다음 아파치의 httpcomponents lib 디렉토리의 URIBuilder 클래스를 사용

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

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' 클래스에 어떤 라이브러리를 사용하나요? –

+0

import android.net.Uri; –

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

힌트 :'문자열 PARAM = URLDecoder.decode (PARAM, "UTF-8") 추가;'루프 내에서 – Marckaraujo

1

UriComponentsBuilder 사용할 수있다.

MultiValueMap<String, String> queryParams = 
      UriComponentsBuilder.fromUriString(url).build().getQueryParams(); 
[이름 - 값 컬렉션으로 URI 문자열 구문 분석]의
관련 문제