Let's say I have a string with an xml many occurences of <tagA>:
String example = " (...) some xml here (...)
<tagA>283940</tagA>
(...) some xml here (...)
<tagA>& 9940</tagA>
<tagA>- 99440</tagA>
<tagA>< 99440</tagA>
<tagA>99440</tagA>
(...) more xml here (...) "
The content should contain only digits, but sometimes it has a random character followed by a whitespace and the the digits.
I want to remove the unwanted character and the whitespace. How to do that?
So far I know I should be looking for a regex "<tagA>. [0-9]*<\/tagA>" but I am stuck here.
I want to replace the characters because among those characters there are "&", ">", "<" signs which make the xml invalid (which prevents me from treating this as an XML).
The regex that you're looking for is:
<(\w+)>(\D{0,})(\d+)
On the search Group 1 you'll get the TAG, on the Group 2 you'll get your weird stuff (everything that is not a digit) and in Group 3 there's the number.
There's an "enhanced version" of this regex that might work in more situations: (\w{0,})(<\w+>)(\D{0,})(\d+)(\D{0,})(<\/\w+>)(\w{0,})
This will place in the Group 1 any whitespace that might be before the tag. Group 7 will take care of the trailing whitespaces.
Group 2 and 6 will match the opening tag and closing tag.
Group 3 and 5 will match any weird character that you might have between your value.
Group 4 will contain your value.
With the String::replaceAll, you can filter and sanitize by printing only the group 2, 4 and 6, getting rid of the rest.
//input data
String s = "<tagA>283940</tagA>\n" +
" <tagA>& 9940<</tagA>\n" +
" <tagA>- 99440</tagA>\n" +
" <tagA>< 99440</tagA>\n" +
" <tagA>99440</tagA>"
+ "<13243> asdfasdf </>";
String replaced = s.replaceAll("(\\s{0,})(<\\w+>)(\\D{0,})(\\d+)(\\D{0,})(<\\/\\w+>)(\\s{0,})", "$2$4$6");
System.out.println(replaced);
Output: <tagA>283940</tagA><tagA>9940</tagA><tagA>99440</tagA><tagA>99440</tagA><tagA>99440</tagA><13243> asdfasdf </>
Related
For my Java app, i have a string that looks like:
value1: *sample", test
test: "test"
newtest: *newtest"
I need to match the character " when the string starts with *.
Tried the regex:
"(?!.*")
But this selected all the " in the input.
Was planning to replaceAll(regex, "") to remove the character.
Desired Output:
value1: *sample, test
test: "test"
newtest: *newtest
How do i get this output?
You can use
.replaceAll("(\\*\\w+)\"", "$1")
Details:
(\*\w+) - Group 1 ($1 refers to the text captured in this group)
" - a " char (just matched, not captured, so eventually removed).
I am trying to mask the logs by chaining replace regex in logback.xml file.
%replace(%replace(%msg){'"email":(.*?),','"email":"****"'}){'"phone":(.*?),','"phone":"****"'}))
It's working, but is there any other regex solution instead of regex replace chaining?
Can we use regex something like this?
(%replace(%msg){'"(email|phone)":(:*?)','"***",'}
I tried the above but the format is not proper.
Required output is:
{"email":"****","phone":"****"}
You can use
(%replace(%msg){'"(email|phone)":[^,]*,?','"$1":"****"'})
The "(email|phone)":[^,]*,? regex matches
" - a " char
(email|phone) - Group 1 ($1): email or phone string
": - a ": string
[^,]* - zero or more chars other than a comma
,? - an optional , char.
The replacement is "$1":"****": " + Group 1 value + ":"***".
See the regex demo.
I have a string that looks like this:
analitics#gmail.com#5
And it represents my userId.
I have to send that userId as parameter to the function and send it in the way that I remove number 5 after second # and append new number.
I started with something like this:
userService.getUser(user.userId.substring(0, userAfterMigration.userId.indexOf("#") + 1) + 3
What is the best way of removing everything that comes after the second # character in string above using Java?
Here is a splitting option:
String input = "analitics#gmail.com#5";
String output = String.join("#", input.split("#")[0], input.split("#")[1]) + "#";
System.out.println(output); // analitics#gmail.com#
Assuming your input would only have two at symbols, you could use a regex replacement here:
String input = "analitics#gmail.com#5";
String output = input.replaceAll("#[^#]*$", "#");
System.out.println(output); // analitics#gmail.com#
You can capture in group 1 what you want to keep, and match what comes after it to be removed.
In the replacement use capture group 1 denoted by $1
^((?:[^#\s]+#){2}).+
^ Start of string
( Capture group 1
(?:[^#\s]+#){2} Repeat 2 times matching 1+ chars other than #, and then match the #
) Close group 1
.+ Match 1 or more characters that you want to remove
Regex demo | Java demo
String s = "analitics#gmail.com#5";
System.out.println(s.replaceAll("^((?:[^#\\s]+#){2}).+", "$1"));
Output
analitics#gmail.com#
If the string can also start with ##1 and you want to keep ## then you might also use:
^((?:[^#]*#){2}).+
Regex demo
The simplest way that would seem to work for you:
str = str.replaceAll("#[^.]*$", "");
See live demo.
This matches (and replaces with blank to delete) # and any non-dot chars to the end.
I want to convert a software version number into a github tag name by regular expression.
For example, the version of ognl is usually 3.2.1. What I want is the tag name OGNL_3_2_1
So we can use String::replaceAll(String regex, String replacement) method like this
"3.2.1".replaceAll("(\d+).(\d+).(\d+)", "OGNL_$1_$2_$3")
And we can get the tag name OGNL_3_2_1 easily.
But when it comes to 3.2, I want the regex still working so I change it into (\d+).(\d+)(?:.(\d+))?.
Execute the code again, what I get is OGNL_3_2_ rather than OGNL_3_2. The underline _ at the tail is not what I want. It is resulted by the null group for $3
So how can I write a suitable replacement to solve this case?
When the group for $3 is null, the underline _ should disappear
Thanks for your help !!!
You can make the last . + digits part optional by enclosing it with an optional non-capturing group and use a lambda as a replacement argument with Matcher.replaceAll in the latest Java versions:
String regex = "(\\d+)\\.(\\d+)(?:\\.(\\d+))?";
Pattern p = Pattern.compile(regex);
String s="3.2.1";
Matcher m = p.matcher(s);
String result = m.replaceAll(x ->
x.group(3) != null ? "OGNL_" + x.group(1) + "_" + x.group(2) + "_" + x.group(3) :
"OGNL_" + x.group(1) + "_" + x.group(2) );
System.out.println(result);
See the Java demo.
The (\d+)\.(\d+)(?:\.(\d+))? pattern (note that literal . are escaped) matches and captures into Group 1 any one or more digits, then matches a dot, then captures one or more digits into Group 2 and then optionally matches a dot and digits (captured into Group 3). If Group 3 is not null, add the _ and Group 3 value, else, omit this part when building the final replacement value.
I am doing some string replace in SQL on the fly.
MySQLString = " a.account=b.account ";
MySQLString = " a.accountnum=b.accountnum ";
Now if I do this
MySQLString.replaceAll("account", "account_enc");
the result will be
a.account_enc=b.account_enc
(This is good)
But look at 2nd result
a.account_enc_num=a.account_enc_num
(This is not good it should be a.accountnum_enc=b.accountnum_enc)
Please advise how can I achieve what I want with Java String Replace.
Many Thanks.
From your comment:
Is there anyway to tell in Regex only replace a.account=b.account or a.accountnum=b.accountnum. I do not want accountname to be replace with _enc
If I understand correctly you want to add _enc part only to account or accountnum. To do this you can use
MySQLString = MySQLString.replaceAll("\\baccount(num)?\\b", "$0_enc");
(num)? mean that num is optional so regex will accept account or accountnum
\\b at start mean that there can be no letters, numbers or "_" before account so it wont accept (affect) something like myaccount, or my_account.
\\b at the end will prevent other letters, numbers or "_" after account or accountnum.
It's hard to extrapolate from so few examples, but maybe what you want is:
MySQLString = MySQLString.replaceAll("account\\w*", "$0_enc");
which will append _enc to any sequence of letters, digits, and underscores that starts with account.
try
String s = " a.accountnum=b.accountnum ".replaceAll("(account[^ =]*)", "$1_enc");
it means replace any sequence characters which are not ' ' or '=' which starts the word "account" with the sequence found + "_enc".
$1 is a reference to group 1 in regex; group 1 is the expression in parenthesis (account[^ =]+), i.e. our sequence
See http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html for details