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
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:
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.
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);
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.