1

I have a query string that could be:

/fr/hello?language=en

or

/fr/welcome?param1=222&param2=aloa&language=en

or

/it/welcome?param1=222&language=en&param2=aa

I would like to remove from each query string the parameter language with its value, therefore the results would be:

/fr/hello

and

/fr/welcome?param1=222&param2=aloa

and

/it/welcome?param1=222&param2=aa

EDIT: The length of the value of the parameter could be more than 2

Does anybody know any good regex expression to use in String.replaceAll([regex],[replace]) ?

cloudy_weather
  • 2,837
  • 12
  • 38
  • 63

6 Answers6

5

Use the below regex and replace the matched strings with empty string,

[&?]language.*?(?=&|\?|$)

DEMO

Example code:

String s1 = "/fr/welcome?param1=222&param2=aloa&language=en";
String s2 = "/fr/welcome?language=en";
String s3 = "/fr/welcome?param1=222&language=en&param2=aa";
String m1 = s1.replaceAll("[&?]language.*?(?=&|\\?|$)", "");
String m2 = s2.replaceAll("[&?]language.*?(?=&|\\?|$)", "");
String m3 = s3.replaceAll("[&?]language.*?(?=&|\\?|$)", "");
System.out.println(m1);
System.out.println(m2);
System.out.println(m3);

Output:

/fr/welcome?param1=222&param2=aloa
/fr/welcome
/fr/welcome?param1=222&param2=aa

IDEONE 1 or IDEONE 2

Avinash Raj
  • 172,303
  • 28
  • 230
  • 274
  • I can't understand why I doesn't match in my code: queryString.replaceAll("[&?]language.*?(?=&|\\?|$)", ""); – cloudy_weather Jul 16 '14 at 12:03
  • but it does not work for this: /en/welcome?language=en – cloudy_weather Jul 16 '14 at 12:08
  • @daniele now see the ideone link. – Avinash Raj Jul 16 '14 at 12:12
  • 2
    Does not work for `/it/welcome?language=en&param1=222` which ends up as `/it/welcome&param1=222` (query does not start with ? anymore). As a solution, one can split of the query string after the `?` in a first step, then use `[&]language.*?(?=&|\?|$)` for the replacement on the query string, and later build the full URL again using `path + "?" + replacedQuery`. – Alexander Klimetschek Jan 26 '16 at 01:28
  • Correcting myself, the regex needs to be: `(&language=[^&]*|language=[^&]*?(&|$))` Separating the two cases of whether it starts with `&` or optionally ends with `&` and using negative sets instead of the lookahead. Also note that I included the `=`, otherwise you would remove all parameters that start with `language`, for example `languageSettings=`, too. – Alexander Klimetschek Jan 26 '16 at 01:46
  • 1
    @AvinashRaj for input /fr/welcome?language=en&a=b gives /fr/welcome&a=b – Vigneshwaran Mar 03 '16 at 06:25
  • @Vigneshwaran ask a new question. – Avinash Raj Mar 03 '16 at 06:37
  • I think @Vigneshwaran's point is a good one, and should be addressed by the answer (i.e. it does not warrant its own question as suggested). There's nothing in the question that should lead one to believe that the "language" query parameter could never be the first of multiple. This answer's regex mangles that use case, resulting in a wrong result. – M. Justin May 24 '21 at 15:10
5

You could use regex with replaceAll()

public static void main(String[] args) {
    String s1 = "/fr/welcome?language=en";
    String s2 = "/fr/welcome?param1=222&param2=aloa&language=en";
    String s3 = "/fr/welcome?param1=222&language=en&param2=aa";
    String pattern = "[?&]language=.{2}"; // use pattern = "([?&]language=\\w+)"; for more than 2 letters after language ==.
    System.out.println(s1.replaceAll(pattern, ""));
    System.out.println(s2.replaceAll(pattern, ""));
    System.out.println(s3.replaceAll(pattern, ""));
}

o/p :

/fr/welcome
/fr/welcome?param1=222&param2=aloa
/fr/welcome?param1=222&param2=aa
TheLostMind
  • 35,966
  • 12
  • 68
  • 104
  • 1
    This messes up the URL if there are more than one query parameters and the first one is "language". In this case, the "?" is removed, so the query parameters are no longer treated as query parameters, but instead as part of the URL path. – M. Justin May 24 '21 at 18:38
1

This regexp should help you:

"language=\\w{2}"
Jens
  • 67,715
  • 15
  • 98
  • 113
1

I would like to remove from each query string the parameter language with its value,...

You can use replaceAll.

String s="/fr/welcome?language=en";
s=s.replaceAll("(\\?|&)language=\\w+", "");
  • (\\?|&) group will match ? or &
  • \\w+ will match one or more word character
akash
  • 22,664
  • 11
  • 59
  • 87
  • This messes up the URL if there are more than one query parameters and the first one is "language". In this case, the "?" is removed, so the query parameters are no longer treated as query parameters, but instead as part of the URL path. – M. Justin May 24 '21 at 18:39
1

This will remove any parameter properly, even if it is placed more than one (for example="/fr/welcome?language=en&param1=222&param2=aloa")

public String removeParamFromUrl(final String url, final String param) {
    if (StringUtils.isNotBlank(url)) {
        return url.replaceAll("&" + param + "=[^&]+", "")
                .replaceAll("\\?" + param + "=[^&]+&", "?")
                .replaceAll("\\?" + param + "=[^&]+", "");
    } else {
        return url;
    }
}
Bahadir Tasdemir
  • 10,325
  • 4
  • 49
  • 61
0

Rather than using a regex, it may be better to use a dedicated URI-manipulation API to remove the query parameter. The Spring UriComponentsBuilder class can be used to remove the given query parameter, retaining the rest. I'm assuming a Spring-specific solution is acceptable, as this question is tagged with .

private static String removeQueryParam(String url) {
    return UriComponentsBuilder.fromUriString(url)
            .replaceQueryParam("language")
            .build()
            .toUriString();
}

From the question as asked, it's unclear why or whether a regex-based solution using String.replaceAll is necessary, or whether instead any Java or Spring-based solution would be acceptable. In other words, this may be an XY problem where the goal is to remove the "language" query parameter while retaining all other query parameters, and there's no particular reason a regex needs to be involved in the solution.

M. Justin
  • 14,487
  • 7
  • 91
  • 130