Java - Regex String replacement - java

I want to replace some parts of a String with Regex. It's the 192001Z part of the string I want to replace.
Code:
String met = "192001Z 17006KT 150V210 CAVOK 11/07 Q1004 NOSIG";
String regexZ = "[0-9].{5}Z";
met = met.replaceAll(regexZ, "${.now?string(\"ddHHmm\")}Z");
I get an error when I want to replace a part of the String with ${.now?string(\"ddHHmm\")}Z.
But when I e.g. replace ${.now?string(\"ddHHmm\")}Z with ThisNeedsToBeReplaced everything works just fine. So my guess is that something is wrong with the string I want to use to replace parts of my original string (met).
The error I receive is Illegal group reference.
Does anyone have an idea what's wrong with ${.now?string(\"ddHHmm\")}Z?

You need to use:
met = met.replaceAll("\\b\\d{6}Z\\b", "\\${.now?string(\"ddHHmm\")}Z");
Correct regex to match 192001Z is \b\d{6}Z\b
You need to escape $ in replacement as well otherwise it is considered a back reference e.g. $1, $2 etx.

Related

Java/Scala regex expression

I am a little unfamiliar with regex. I have a string along the following lines
val str20 = "unit/virtual-ExtractMe/domain-testing-ExtracMe-IgnoreMe"
The word I want to extract is "ExtractMe"(the first one that is seen above right before domain-. The format is of string is going to be same in the start but will change after the second slash and I need to ignore whatever is written after the second slash. My interest is to get whatever is written between virtual- and second / . In this case it is the first occurrence of the word ExtractMe. for example if I have this
val str20 = "unit/virtual-YouGotMe/domain-testing-ExtracMe-IgnoreMe"
The regex should get me the word "YouGotMe" as it is between virtual- and the second forward slash
This /virtual-(.*?)/ will get you all the matches in a group. You just have to get the first one. See : https://regex101.com/r/KX9VTt/2
In Scala regex, there is no need to escape the /, but if you are doing them in Java directly, you will need to escape them.
In Scala, you can use findFirstMatchIn to extract the first matched group as follows:
val pattern = """virtual-(.*?)/""".r
val str20 = "unit/virtual-ExtractMe/domain-testing-ExtracMe-IgnoreMe"
pattern.
findFirstMatchIn(str20).
map(_.group(1)).
getOrElse("Error: No Match!!!")
res1: String = ExtractMe
val str20 = "unit/virtual-YouGotMe/domain-testing-ExtracMe-IgnoreMe"
pattern.
findFirstMatchIn(str20).
map(_.group(1)).
getOrElse("Error: No Match!!!")
res2: String = YouGotMe

Escape special characters using Regex in java [duplicate]

Does Java have a built-in way to escape arbitrary text so that it can be included in a regular expression? For example, if my users enter "$5", I'd like to match that exactly rather than a "5" after the end of input.
Since Java 1.5, yes:
Pattern.quote("$5");
Difference between Pattern.quote and Matcher.quoteReplacement was not clear to me before I saw following example
s.replaceFirst(Pattern.quote("text to replace"),
Matcher.quoteReplacement("replacement text"));
It may be too late to respond, but you can also use Pattern.LITERAL, which would ignore all special characters while formatting:
Pattern.compile(textToFormat, Pattern.LITERAL);
I think what you're after is \Q$5\E. Also see Pattern.quote(s) introduced in Java5.
See Pattern javadoc for details.
First off, if
you use replaceAll()
you DON'T use Matcher.quoteReplacement()
the text to be substituted in includes a $1
it won't put a 1 at the end. It will look at the search regex for the first matching group and sub THAT in. That's what $1, $2 or $3 means in the replacement text: matching groups from the search pattern.
I frequently plug long strings of text into .properties files, then generate email subjects and bodies from those. Indeed, this appears to be the default way to do i18n in Spring Framework. I put XML tags, as placeholders, into the strings and I use replaceAll() to replace the XML tags with the values at runtime.
I ran into an issue where a user input a dollars-and-cents figure, with a dollar sign. replaceAll() choked on it, with the following showing up in a stracktrace:
java.lang.IndexOutOfBoundsException: No group 3
at java.util.regex.Matcher.start(Matcher.java:374)
at java.util.regex.Matcher.appendReplacement(Matcher.java:748)
at java.util.regex.Matcher.replaceAll(Matcher.java:823)
at java.lang.String.replaceAll(String.java:2201)
In this case, the user had entered "$3" somewhere in their input and replaceAll() went looking in the search regex for the third matching group, didn't find one, and puked.
Given:
// "msg" is a string from a .properties file, containing "<userInput />" among other tags
// "userInput" is a String containing the user's input
replacing
msg = msg.replaceAll("<userInput \\/>", userInput);
with
msg = msg.replaceAll("<userInput \\/>", Matcher.quoteReplacement(userInput));
solved the problem. The user could put in any kind of characters, including dollar signs, without issue. It behaved exactly the way you would expect.
To have protected pattern you may replace all symbols with "\\\\", except digits and letters. And after that you can put in that protected pattern your special symbols to make this pattern working not like stupid quoted text, but really like a patten, but your own. Without user special symbols.
public class Test {
public static void main(String[] args) {
String str = "y z (111)";
String p1 = "x x (111)";
String p2 = ".* .* \\(111\\)";
p1 = escapeRE(p1);
p1 = p1.replace("x", ".*");
System.out.println( p1 + "-->" + str.matches(p1) );
//.*\ .*\ \(111\)-->true
System.out.println( p2 + "-->" + str.matches(p2) );
//.* .* \(111\)-->true
}
public static String escapeRE(String str) {
//Pattern escaper = Pattern.compile("([^a-zA-z0-9])");
//return escaper.matcher(str).replaceAll("\\\\$1");
return str.replaceAll("([^a-zA-Z0-9])", "\\\\$1");
}
}
Pattern.quote("blabla") works nicely.
The Pattern.quote() works nicely. It encloses the sentence with the characters "\Q" and "\E", and if it does escape "\Q" and "\E".
However, if you need to do a real regular expression escaping(or custom escaping), you can use this code:
String someText = "Some/s/wText*/,**";
System.out.println(someText.replaceAll("[-\\[\\]{}()*+?.,\\\\\\\\^$|#\\\\s]", "\\\\$0"));
This method returns: Some/\s/wText*/\,**
Code for example and tests:
String someText = "Some\\E/s/wText*/,**";
System.out.println("Pattern.quote: "+ Pattern.quote(someText));
System.out.println("Full escape: "+someText.replaceAll("[-\\[\\]{}()*+?.,\\\\\\\\^$|#\\\\s]", "\\\\$0"));
^(Negation) symbol is used to match something that is not in the character group.
This is the link to Regular Expressions
Here is the image info about negation:

How to skip a specific word when replace the String using regexp in java

Consider the string
String s = "H_ello pe_rfec_t wor_ld"
I want to replace all '_' symbols on... no matter what, let`s say on '1', except those which are placed inside the 'pe_rfec_t'.
I could not find any solution even to just skip the word 'pe_rfec_t':
s = s.replaceAll("(?<=pe_rfec_t).*|.*(?=pe_rfec_t)", "1");
looks nice at a glance but results to:
11pe_rfec_t1 //instead of 1111111pe_rfec_t1111111
Ideally I need the following result:
Hello pe_rfec_t world
Could anyone help me please?
You can use alternation and captured group:
String str = "H_ello pe_rfec_t wor_ld";
String repl = str.replaceAll("(pe_rfec_t)|_", "$1");
//=> Hello pe_rfec_t world
RegEx Demo
Here in alternation we match first pe_rfec_t and capture it in group #1. In repalcement we put $1 (back-reference to group #1) back.

How can I manipulate part of a string in java using regular expressions

I have a string that looks like this:
String pathTokenString = "CMS/{brandPath}/Shows/{showPath}";
I want to remove the Shows part and everything that follows. I also want to replace "{brandPath}" with a token that I'm given.
This has been my approach. However, my string isn't getting updated at all:
//remove the '/Shows/{showPath}'
pathTokenString = pathTokenString.replace("/Shows$", "");
//replace passed in brandPath in the tokenString
String answer = pathTokenString.replace("{(.*?)}", brandPath);
Is there something wrong with my regular expressions?
You should use the replaceAll method instead of replace when you want to pass a regex string as the pattern to be replaced. Also your regex patterns should be updated:
pathTokenString = pathTokenString.replaceAll("/Shows.*$", "");
// The curly braces need to be escaped because they denote quantifiers
String answer = pathTokenString.replaceAll("\\{(.*?)\\}", brandPath);

most elegant way of escaping $ in java

I have a base String "abc def", I am trying to replace my base string with "abc$ def$" using replaceFirst(), which is running into errors as $ is not escaped.
I tried doing it with Pattern and Matcher APIs, as given below,
newValue = "abc$ def$";
if(newValue.contains("$")){
Pattern specialCharacters = Pattern.compile("$");
Matcher newMatcherValue = specialCharacters.matcher(newValue) ;
newValue = newMatcherValue.replaceAll("\\\\$") ;
}
This runs into an error. Is there any elegant way of replacing my second string "abc$ def$" with "abc\\\\$ def\\\\$" so as to use the replacefirst() API successfully?
Look at Pattern.quote() to quote a regex and Matcher.quoteReplacement() to quote a replacement string.
That said, does this do what you want it to?
System.out.println("abc def".replaceAll("([\\w]+)\\b", "$1\\$"));
This prints out abc$ def$
You can use replaceAll just in one step:
String newValueScaped = newValue.replaceAll("\\$", "\\\\$")
$ has a special mining in regex, so you need to scape it. It's used to match the end of the data.

Categories

Resources