24

在Java中我有:

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()正在返回错误。m.groups()正在回归IllegalArgumentException

我究竟做错了什么?

4

7 回答 7

43

它不必是正则表达式。因为我认为没有标准的方法来处理这件事,所以我使用了我从某个地方复制的东西(也许做了一些修改):

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,在您的情况下,您需要获取第一个列表元素。

于 2011-05-05T17:58:20.937 回答
17

不确定您如何使用findand group,但这很好用:

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)或使用带有环视的正则表达式:

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

它在与上面相同的 Java 代码中工作。它试图在 之后立即找到一个起始位置depCity=。然后匹配任何东西,但尽可能少地匹配,直到它到达一个点面对&或输入结束。

于 2011-05-05T19:36:43.233 回答
15

我有三种解决方案,第三种是博卓的改进版。

首先,如果你不想自己写东西而只是使用一个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;
}
于 2014-08-13T15:13:34.330 回答
10

如果您正在开发 Android 应用程序,请尝试以下操作:

String yourParam = null;
Uri uri = Uri.parse(url);
try {
    yourParam = URLDecoder.decode(uri.getQueryParameter(PARAM_NAME), "UTF-8");
} catch (UnsupportedEncodingException exception) {
    exception.printStackTrace();
}        
于 2016-10-03T13:46:59.777 回答
7

如果类路径中存在spring-web ,则可以使用UriComponentsBuilder 。

MultiValueMap<String, String> queryParams =
            UriComponentsBuilder.fromUriString(url).build().getQueryParams();
于 2017-09-10T12:46:03.633 回答
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);
            }
于 2016-12-19T06:40:35.560 回答
0

相同但使用 jsonobject:

public static JSONObject getQueryParams2(String url) {
    JSONObject json = new JSONObject();
    try {
        String[] urlParts = url.split("\\?");
        JSONArray array = new  JSONArray();
        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");
                    if(json.has(key)) {
                        array = json.getJSONArray(key);
                        array.put(value);
                        json.put(key, array);
                        array = new JSONArray();
                    } else {
                        array.put(value);
                        json.put(key, array);
                        array = new JSONArray();
                    }
                }
            }
        }
        return json;
    } catch (Exception ex) {
        throw new AssertionError(ex);
    }
}
于 2019-12-04T21:46:51.550 回答