16

我查看了 Java API 和一些常见的第 3 方库,但我找不到合适的方法来执行 String.replaceAll 所做的工作,除了 StringBuilder。

我知道只需一点工作,就可以为 StringBuffer 完成,但我不想走这条路,因为 StringBuffer 速度较慢。

有谁知道任何 3rd 方实用程序,或者是否有一段快速的代码来实现此功能?

4

4 回答 4

11

String.replaceAll只是一种方便的方法Matcher.replaceAllMatcher是在 Java 中使用正则表达式的“实际”方式,它允许更复杂的用例。

此外,任何可以用正则表达式方法完成的事情String都可以用类似的方法完成Matcher。美妙之处在于,它Matcher不仅可以与 s 一起使用StringMatchers 可以用于任何(接口,CharSequenceStringBuilder、和实现)。所以你可以简单地做:StringBufferStringCharBuffer

import java.util.regex.*;

...

StringBuilder sb = new StringBuilder();
sb.append("This works with StringBuffers");
Pattern p = Pattern.compile("\\Buffer\\B");
Matcher m = p.matcher(sb);
System.out.println(m.replaceAll("uilder"));

会输出This works with StringBuilders

工作演示。

于 2013-06-28T15:13:46.437 回答
3

Regex does not modify a mutable CharSequence internally. Regex parses a CharSequence to return a String, where String is the result. StringBuffer is an exception as there is special handling - as for StringBuilder being CharSequence, you have to modify it with a match result.

What you can do instead:

// Class
private static final Pattern MY_PATTERN = Pattern.compile("my|regex");

{ // Method
    StringBuilder builder;
    // ...

    Matcher m = MY_PATTERN.matcher(builder);
    builder.replace(0, builder.length(), m.replaceAll("<b>$0</b>"));
}

View a test code demo!

于 2014-07-12T06:36:44.447 回答
3

我不想走这条路,因为 StringBuffer 比较慢。

没错,但有通常的过早优化警告,更重要的是,现代 JVM 在某些情况下使用逃逸分析来移除 StringBuffer/Vector/HashTable 锁,因此一旦发生优化,性能将大致相同。

于 2014-07-12T06:45:04.337 回答
0

Apache Harmony Matcher 源代码似乎完全可以重新使用,StringBuilder而不是当前使用的StringBuffer,只需移动到不同的包。它似乎并没有拖累很多依赖。即使对于商业项目,文件开头的 Apache 许可证也可能不错。

GNU Classpath代码也可以重用,但那里的许可证更加困难(您需要发布 Matcher 的更改版本,但可能不需要发布其余代码)。与原始 Sun 的实现相同,可以OpenJDK 项目中找到。

于 2013-06-28T14:45:30.287 回答