1

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"
3
  • Give several examples of input, and for each input, show the desired output for that input. Commented Feb 4, 2017 at 0:08
  • @DavidChoweller added few examples Commented Feb 6, 2017 at 18:42
  • @user3366706 take a look for you update that I have written Commented Feb 7, 2017 at 21:09

2 Answers 2

2

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 }.

Java code:

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
Sign up to request clarification or add additional context in comments.

2 Comments

this one matches even with single ${...} like if string is "text1${text2}text3" then text2 matches your regex. but it would be nice if I can get only that matches "inner" ${}, so "text1${text2}text3" should not have anything matching, but string like this "text1${text2${text3}}" should match the inner text3 substring
0

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

demo


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

2 Comments

with slight modification it works for what I wanted \${.*\$\{(.*?)\}.*?\} There is a slight improvement I need from this regex. For example: in this string text1${text2${that}text4${this}text5} it captures only 'this', ie. only one inner substring. I could not make it to capture all matching substring in one go, ie. capture 'this', and 'that' in one go.
@user3366706 your ask does not make sense to me. You should know that regexes are very sensitive and I wrote this for your purpose that you wrote above. If you want a thing for both or anything just update your question. Also this text1${text2${that}text4${this}text5} is difference from one you have written. So think and exactly tell what you want.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.