Reputation: 1599
I need to match or replace a part of string like below, but I couldn't write the exact regular expression for that in java.
String:
text1${text2${text3}text4}text5
Expected regex should match the test3 alone, ie. anything inside "inner" ${}. Above example has an outer ${...} and an inner ${...}, like ...${...${...}...}.... And test3 is inside the "inner ${} which is what I want.
The following regex captures the entire content within ${...}, not just the content of "inner" ${...}
\$\{(.*?)\}
More Examples:
text1${text2${text3}text4}text5 - match "text3"
text1text2${text3}text4text5 - should not match anything
text1${text2${text3}text4text5 - should not match anything
Update:
text1${text2${text3}${text4}text5} - match "text3" and "text4"
Upvotes: 1
Views: 377
Reputation: 23774
First you need to match the entire between the first {
and the last }
and after that you can match what you want by using match-group.
what you want
{.*\{(.*?)\}.*?\}
In the first step it match {text2${text3}
and after that you should use math-group
I am not familiar with Java but I know a little with Perl and C++ and I think it works in Java because it is easy and not complex
Test with Perl
echo 'text1${text2${text3}text4}text5' | perl -lne '/\{.*\{(.*?)\}.*?\}/ && print $1'
output
text3
So in you Java code use $1
that's it.
For your update that you wrote, you have 2 choices one with a loop
over your string and other with four match-group
First with a while loop
echo 'text1${text2${text3}${text4}text5}' | perl -lne 'print $2 while /(\${)(\w+)(\$?})/g'
text3
text4
How does it work? very easy. It first match ${text3}
and here \w+
would be text3 then it goes ahead and match ${text4}
and again \w+
would be text4
(\${)(\w+)(\$?})
prove
Second with non-loop
echo 'your-string' | perl -lne ' /(\${)(\w+)(\$?})\1(\w+)\3/g && print $2," ",$4'
This one also easy. It first matches text3 and then matches text4 and puts them in $2
and $4
. that's it.
(\${)(\w+)(\$?})\1(\w+)\3
prove
NOTE
With while loop you need to use g flag and you can not ignore it but for second no problem.
Again
Upvotes: 0
Reputation: 626748
The .
matches both {
and }
. You need to exclude matching {
and }
:
\$\{([^{}]*)}
^^^^^
See the regex demo. The [^{}]*
is a negated character class matching 0+ chars other than {
and }
.
String str = "text1${text2${text3}text4}text5";
Pattern p = Pattern.compile("\\$\\{([^{}]*)}");
Matcher m = p.matcher(str);
while (m.find()) {
System.out.println(m.group(1));
}
// => text3
Upvotes: 2