Dans Java j'ai:
String params = "depCity=PAR&roomType=D&depCity=NYC";
Je veux obtenir les valeurs des paramètres depCity
(PAR, NYC).
J'ai donc créé regex:
String regex = "depCity=([^&]+)";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(params);
m.find()
retourne false. m.groups()
renvoie IllegalArgumentException
.
Qu'est-ce que je fais mal?
Il n'est pas nécessaire que ce soit regex. Comme je pense qu'il n'y a pas de méthode standard pour gérer cette chose, j'utilise quelque chose que j'ai copié quelque part (et peut-être un peu modifié):
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);
}
}
Ainsi, lorsque vous l'appelez, vous obtiendrez tous les paramètres et leurs valeurs. La méthode gère les paramètres à valeurs multiples, d'où le List<String>
plutôt que String
, et dans votre cas, vous devrez obtenir le premier élément de la liste.
Je ne sais pas comment vous avez utilisé find
et group
, mais cela fonctionne très bien:
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
}
Cependant, si vous ne voulez que les valeurs, pas la clé depCity=
, Vous pouvez soit utiliser m.group(1)
soit utiliser une expression régulière avec des contournements:
Pattern p = Pattern.compile("(?<=depCity=).*?(?=&|$)");
Il fonctionne dans le même code Java comme ci-dessus. Il essaie de trouver une position de départ juste après depCity=
. Correspond ensuite à tout mais aussi peu que possible jusqu'à ce qu'il atteigne un point face à &
Ou fin de saisie.
Si vous développez une application Android Android, essayez ceci:
String yourParam = null;
Uri uri = Uri.parse(url);
try {
yourParam = URLDecoder.decode(uri.getQueryParameter(PARAM_NAME), "UTF-8");
} catch (UnsupportedEncodingException exception) {
exception.printStackTrace();
}
J'ai trois solutions, la troisième est une version améliorée de Bozho.
Tout d'abord, si vous ne voulez pas écrire vous-même et utiliser simplement une lib, utilisez la classe URIBuilder de lib de httpcomponents d'Apache: http://hc.Apache.org/httpcomponents-client-ga/httpclient/apidocs/ org/Apache/http/client/utils/URIBuilder.html
new URIBuilder("http://...").getQueryParams()...
Seconde:
// 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;
}
Troisième:
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;
}
Si spring-web est présent sur classpath, riComponentsBuilder peut être utilisé.
MultiValueMap<String, String> queryParams =
UriComponentsBuilder.fromUriString(url).build().getQueryParams();
Solution simple créez la carte à partir de tous les noms et valeurs de paramètres et utilisez-la :).
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);
}