1

I have a string which contains many <xxx> values.

I want to retrive the value inside <>, do some manipulation and re-insert the new value into the string.

What I did is

input = This is <abc_d> a sample <ea1_j> input <lmk_02> string
while(input.matches(".*<.+[\S][^<]>.*"))
{
   value = input.substring(input.indexOf("<") + 1, input.indexOf(">"));
   //calculate manipulatedValue from value
   input = input.replaceFirst("<.+>", manipulatedValue);
}

but after the first iteration, value contains abc_d> a sample <ea1_j> input <lmk_02. I believe indexOf(">") will give the first index of ">". Where did I go wrong?

3 Answers 3

2

This is a slightly easier way of accomplishing what you are trying to do:

String input = "This is <abc_d> a sample <ea1_j> input <lmk_02> string";
Matcher matcher = Pattern.compile("<([^>]*)>").matcher(input);
StringBuffer sb = new StringBuffer();
while(matcher.find()) {
    matcher.appendReplacement(sb, manipulateValue(matcher.group(1)));
}
matcher.appendTail(sb);
System.out.println(sb.toString());
Sign up to request clarification or add additional context in comments.

5 Comments

StringBuilder would be the better option to use here, but otherwise your solution looks good, upvote.
@MichaelSchmeißer: I would use it if matcher.appendReplacement() accepted a StringBuilder as parameter.
Oh, I see. I wasn't aware of that (I think it is kinda weird too), so there is nothing to improve in your answer I guess. :)
@MichaelSchmeißer: Yeah, it is kind of weird, this seems like a perfect place to use StringBuilder, but I guess they didn't want to expand the Matcher API.
As per my answer, you may need to use Matcher.quoteReplacement on your replacement string - appendReplacement allows backreferences like $1 to include groups from the match in the replacement (e.g. a pattern of <([^>]*)> and a replacement string of =$1= would change <foo> into =foo=). If you want a literal $ in the replacement string you have to escape it as \$, and thus if you want a literal backslash that has to be doubled. The quoteReplacement method does these substitutions for you.
0

This is a good use case for the appendReplacement and appendTail idiom:

Pattern p = Pattern.compile("<([^>]+)>");
Matcher m = p.matcher(input);
StringBuffer out = new StringBuffer():
while(m.find()) {
  String value = m.group(1);
  // calculate manipulatedValue
  m.appendReplacement(out, Matcher.quoteReplacement(manipulatedValue));
}
m.appendTail(out);

Comments

-1

Try using an escape character \\ to the regex.

1 Comment

At which point should an escape character help in the regex? Also, you should mention that escape characters must occur in pairs in Java regexes.

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.