开发者

Replace text in StringBuilder via regex

开发者 https://www.devze.com 2023-02-07 20:04 出处:网络
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():

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():

StringB开发者_StackOverflow社区uilder 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"); 


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.


I've solved this by adding matcher.reset():

    while (matcher.find())
    {
        sb.replace(matcher.start(), matcher.end(), "x");
        matcher.reset();
    }


This is already a reported bug and I'm guessing they're currently looking into a fix for it. Read more here.


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());
}


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.


Another issue with using StringBuidler.replace() is that that one can't handle capturing groups.

0

精彩评论

暂无评论...
验证码 换一张
取 消