Replace text in StringBuilder via regex

2020-04-07 03:38发布

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"); 

6条回答
家丑人穷心不美
2楼-- · 2020-04-07 04:23

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

    while (matcher.find())
    {
        sb.replace(matcher.start(), matcher.end(), "x");
        matcher.reset();
    }
查看更多
我只想做你的唯一
3楼-- · 2020-04-07 04:28

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.

查看更多
地球回转人心会变
4楼-- · 2020-04-07 04:28

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

查看更多
放我归山
5楼-- · 2020-04-07 04:29

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());
}
查看更多
劳资没心,怎么记你
6楼-- · 2020-04-07 04:33

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.

查看更多
聊天终结者
7楼-- · 2020-04-07 04:36

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

查看更多
登录 后发表回答