通过正则表达式替换 StringBuilder 中的文本

发布于 2024-10-15 04:37:26 字数 383 浏览 1 评论 0原文

我想替换 StringBuilder 中的一些文本。如何做到这一点?

在此代码中,我得到了与 matcher.find() 一致的 java.lang.StringIndexOutOfBoundsException

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

幸福还没到 2024-10-22 04:37:26

让我们有一个总长度为 50 的 StringBuilder,并将前 20 个字符更改为“x”。所以 StringBuilder 缩小了 19,对吧 - 但是初始输入 pattern.matcher(sb) 没有改变,所以最终 StringIndexOutOfBoundsException。

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.

阳光下慵懒的猫 2024-10-22 04:37:26

我通过添加 matcher.reset() 解决了这个问题:

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

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

    while (matcher.find())
    {
        sb.replace(matcher.start(), matcher.end(), "x");
        matcher.reset();
    }
若水般的淡然安静女子 2024-10-22 04:37:26

这已经是一个已报告的错误,我猜他们目前正在研究解决方案。 此处了解更多信息。

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

梨涡 2024-10-22 04:37:26

你不应该这样做。 Matcher 的输入可以是任何 CharSequence,但序列不应更改。像你这样的匹配就像迭代一个集合,同时删除元素,这是行不通的。

不过,也许有一个解决方案:

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

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());
}
揪着可爱 2024-10-22 04:37:26

或许:

    int lookIndex = 0;
    while (lookIndex < builder.length() && matcher.find(lookIndex)) {
        lookIndex = matcher.start()+1;
        builder.replace(matcher.start(), matcher.end(), repl);
    }

...?

带有整数参数的 .find(n) 声称在开始查看指定索引之前重置匹配器。这将解决上面 maartinus 评论中提出的问题。

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.

自我难过 2024-10-22 04:37:26

使用 StringBuidler.replace() 的另一个问题是它无法处理捕获组。

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文