I have a query string that could be:
/fr/hello?language=en
or
/fr/welcome?param1=222¶m2=aloa&language=en
or
/it/welcome?param1=222&language=en¶m2=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¶m2=aloa
and
/it/welcome?param1=222¶m2=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]) ?
Use the below regex and replace the matched strings with empty string,
[&?]language.*?(?=&|\?|$)
DEMO
Example code:
String s1 = "/fr/welcome?param1=222¶m2=aloa&language=en";
String s2 = "/fr/welcome?language=en";
String s3 = "/fr/welcome?param1=222&language=en¶m2=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¶m2=aloa
/fr/welcome
/fr/welcome?param1=222¶m2=aa
IDEONE 1 or IDEONE 2
You could use regex with replaceAll()
public static void main(String[] args) {
String s1 = "/fr/welcome?language=en";
String s2 = "/fr/welcome?param1=222¶m2=aloa&language=en";
String s3 = "/fr/welcome?param1=222&language=en¶m2=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¶m2=aloa
/fr/welcome?param1=222¶m2=aa
This regexp should help you:
"language=\\w{2}"
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
This will remove any parameter properly, even if it is placed more than one (for example="/fr/welcome?language=en¶m1=222¶m2=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;
}
}
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 spring.
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.
Related
I have a string which contains an underscore as shown below:
123445_Lisick
I want to remove all the characters from the String after the underscore. I have tried the code below, it's working, but is there any other way to do this, as I need to put this logic inside a for loop to extract elements from an ArrayList.
public class Test {
public static void main(String args[]) throws Exception {
String str = "123445_Lisick";
int a = str.indexOf("_");
String modfiedstr = str.substring(0, a);
System.out.println(modfiedstr);
}
}
Another way is to use the split method.
String str = "123445_Lisick";
String[] parts = string.split("_");
String modfiedstr = parts[0];
I don't think that really buys you anything though. There's really nothing wrong with the method you're using.
Your method is fine. Though not explicitly stated in the API documentation, I feel it's safe to assume that indexOf(char) will run in O(n) time. Since your string is unordered and you don't know the location of the underscore apriori, you cannot avoid this linear search time. Once you have completed the search, extraction of the substring will be needed for future processing. It's generally safe to assume the for simple operations like this in a language which is reasonably well refined the library functions will have been optimized.
Note however, that you are making an implicit assumption that
an underscore will exist within the String
if there are more than one underscore in the string, all but the first should be included in the output
If either of these assumptions will not always hold, you will need to make adjustments to handle those situations. In either case, you should at least defensively check for a -1 returned from indexAt(char) indicating that '_' is not in the string. Assuming in this situation the entire String is desired, you could use something like this:
public static String stringAfter(String source, char delim) {
if(source == null) return null;
int index = source.indexOf(delim);
return (index >= 0)?source.substring(index):source;
}
You could also use something like that:
public class Main {
public static void main(String[] args) {
String str = "123445_Lisick";
Pattern pattern = Pattern.compile("^([^_]*).*");
Matcher matcher = pattern.matcher(str);
String modfiedstr = null;
if (matcher.find()) {
modfiedstr = matcher.group(1);
}
System.out.println(modfiedstr);
}
}
The regex groups a pattern from the start of the input string until a character that is not _ is found.
However as #Bill the lizard wrote, i don't think that there is anything wrong with the method you do it now. I would do it the same way you did it.
I have a question involving the Replace Method. I saw a question similar to this on here, but I tried to do the replaceFirst but it didn't work for me. Is there, any way I can use the replace method to change a string that results in: Helle, Werld; to get it to result to BE "Hello, World" using the replace method. Is there a way using the replaceFirst method for me to search for the sequence of "le" and replace it with "lo" and also change "We" to "Wo"?. Please see my code below:
public class Printer
{
/**Description: Replacement class
*
*
*/
public static void main(String[] args)
{
String test1Expected = "Hello, World!";
String newString1;
String test1 = "Holle, Werld!";
newString1 = test1.replace('o', 'e');
//Could I do: newString1.replaceFirst("le","lo);
System.out.println("newString1 = " + newString1);
//Output comes out to "Helle, Werld!"
}
}
You can do two regular expressions separatelt one after the other. Please try the following
newString1 = newString1.replaceAll("le", "lo").replaceAll("We", "Wo");
I have a string containing several urls. I want to retrieve the urls containing "thistext" and copy them into another variable named "outputlinks". This is my code.
String links = "http://www.website1.com/thistext
http://www.website1.com/othertext
http://www.website1.com/thistext";
String outputlinks =""; // ??
Assuming you meant:
String links = "http://www.website1.com/thistext\n" +
"http://www.website1.com/othertext\n" +
"http://www.website1.com/thistext";
Then you can do:
public static void main(String[] args) {
String links = "http://www.website1.com/thistext\n" +
"http://www.website1.com/othertext\n" +
"http://www.website1.com/thistext";
String[] linksArray = links.split("\n");
for (String link : linksArray) {
if (link.contains("thistext")) {
System.out.println(link);
}
}
}
First of all use a good separator for your links, like commah, semi colon or something else. Use a string tokenizer to get the individual links and finally search for your term, i.e "thisText" in each of the tokenized strings, using indexOf. That will get the job done for you.
I have to test whether a string is included in another one but without considering case or accents (French accents in this case).
For example the function must return true if I search for "rhone" in the string "Vallée du Rhône".
The Collator is useful for string comparison with accents but does not provide a contains function.
Is there an easy way to do the job ? A regex maybe ?
Additional information :
I just need a true / false return value, I don't care about number of matches or position of the test string in the reference string.
You can use Normalizer to reduce strings to stripped-down versions that you can compare directly.
Edit: to be clear
String normalized = Normalizer.normalize(text, Normalizer.Form.NFD);
String ascii = normalized.replaceAll("[^\\p{ASCII}]", "");
Have a look at Normalizer.
You should call it with Normalizer.Form.NFD as your second argument.
So, that would be:
Normalizer.normalize(yourinput, Normalizer.Form.NFD)
.replaceAll("\\p{InCombiningDiacriticalMarks}+", "")
.toLowerCase()
.contains(yoursearchstring)
which will return true if match (and, of course, false otherwise)
How about this?
private static final Pattern ACCENTS_PATTERN = Pattern.compile("\\p{InCombiningDiacriticalMarks}+");
public static boolean containsIgnoreCaseAndAccents(String haystack, String needle) {
final String hsToCompare = removeAccents(haystack).toLowerCase();
final String nToCompare = removeAccents(needle).toLowerCase();
return hsToCompare.contains(nToCompare);
}
public static String removeAccents(String string) {
return ACCENTS_PATTERN.matcher(Normalizer.normalize(string, Normalizer.Form.NFD)).replaceAll("");
}
public static void main(String[] args) {
System.out.println(removeAccents("Vallée du Rhône"));
System.out.println(removeAccents("rhone"));
System.out.println(containsIgnoreCaseAndAccents("Vallée du Rhône", "rhone"));
}
The normal way to do this is to convert both strings to lowercase without accents, and then use the standard 'contains'.
I have Spring MVC URL's define in Interfaces (just to hold the Constants) like:
String URL_X = "/my-url/{id:[0-9]*}";
String URL_Y = "/my-url/{id:[0-9]*}/blah-blah";
I have a method for my tests that replace the variables in an URL:
private static final String REGEX_PARAMETROS_DA_URL = "(\\{[^\\}]*\\})";
protected String replaceParametersOnURL(String urlSpring, String... params) {
String urlAtual = urlSpring;
for (String parametro : params) {
urlAtual = urlAtual.replaceFirst(REGEX_PARAMETROS_DA_URL, parametro);
}
return urlAtual;
}
I was using this regex: (\{[^\}]*\}) to match the variables and replace it.
But now i have some URL's that have {} on it and i can't find a properly regex to replace the variable with my value.
Is there any method on Spring that replaces the PathVariable value or can anyone help me with this regex?
Given this URL for instance:
/pessoajuridica/{cnpj:[0-9]{14}}-{slug:[a-zA-Z0-9-]+}/sancoes/resumo
The matches must be: {cnpj:[0-9]{14}}and {slug:[a-zA-Z0-9-]+}
Thanks #Matthew. I haven't noticed that the spring test itself can do this!
All i need to do is:
mockMvc.perform(get("/pessoajuridica/{cnpj:[0-9]{14}}-{slug:[a-zA-Z0-9-]+}/sancoes/resumo", var1, var2)) ...