问题
I would like to replace some texts in StringBuilder. How to do this?
In this code I got java.lang.StringIndexOutOfBoundsException
at line with matcher.find()
:
StringBuilder sb = new StringBuilder(input);
Pattern pattern = Pattern.compile(str_pattern);
Matcher matcher = pattern.matcher(sb);
while (matcher.find())
sb.replace(matcher.start(), matcher.end(), "x");
回答1:
Lets have a StringBuilder w/ 50 total length and you change the first 20chars to 'x'. So the StringBuilder is shrunk by 19, right - however the initial input pattern.matcher(sb) is not altered, so in the end StringIndexOutOfBoundsException.
回答2:
I've solved this by adding matcher.reset()
:
while (matcher.find())
{
sb.replace(matcher.start(), matcher.end(), "x");
matcher.reset();
}
回答3:
This is already a reported bug and I'm guessing they're currently looking into a fix for it. Read more here.
回答4:
You shouldn't do it this way. The input to Matcher may be any CharSequence, but the sequence should not change. Matching like you do is like iterating over a Collection while removing elements at the same time, this can't work.
However, maybe there's a solution:
while (matcher.find()) {
sb.replace(matcher.start(), matcher.end(), "x");
matcher.region(matcher.start() + "x".length(), sb.length());
}
回答5:
Maybe:
int lookIndex = 0;
while (lookIndex < builder.length() && matcher.find(lookIndex)) {
lookIndex = matcher.start()+1;
builder.replace(matcher.start(), matcher.end(), repl);
}
...?
.find(n) with an integer argument claims to reset the matcher before it starts looking at the specified index. That would work around the issues raised in maartinus comment above.
回答6:
Another issue with using StringBuidler.replace() is that that one can't handle capturing groups.
来源:https://stackoverflow.com/questions/4829908/replace-text-in-stringbuilder-via-regex