java 使用正则表达式支持替换 StringBuilder 的所有内容?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17366882/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
replaceAll for StringBuilder with regex support?
提问by Jin Kim
I've looked in the Java API and some common 3rd party libraries but I'm unable to find a suitable method that will do what String.replaceAll does, except for StringBuilder.
我查看了 Java API 和一些常见的 3rd 方库,但我找不到合适的方法来执行 String.replaceAll 的功能,除了 StringBuilder。
I know that with a little work, it can be done for StringBuffer, but I don't want to go down this road because StringBuffer is slower.
我知道只要稍加工作,StringBuffer 就可以完成,但我不想走这条路,因为 StringBuffer 速度较慢。
Does anyone know of any 3rd party utilies, or if there is a quick piece of code to implement this functionality?
有谁知道任何 3rd 方实用程序,或者是否有一段快速代码来实现此功能?
回答by Martin Ender
String.replaceAll
is just a convenience method for Matcher.replaceAll
. Matcher
is the "actual" way to use regex in Java and is allows for a lot more sophisticated use cases.
String.replaceAll
只是一个方便的方法Matcher.replaceAll
。Matcher
是在 Java 中使用正则表达式的“实际”方式,并且允许更复杂的用例。
Moreover, anything that can be done with regex methods on String
can be done with similar methods on a Matcher
. The beauty is, that Matcher
s work with more than just String
s: Matcher
s can be obtained for any CharSequence
(an interface, which is implemented by StringBuilder
, StringBuffer
, String
and CharBuffer
). So you can simply do:
此外,凡是能与正则表达式的方法上进行String
可以用一个类似的方法来完成Matcher
。美妙之处在于,这Matcher
不仅仅是String
s:Matcher
s 可以为 any CharSequence
(一个接口,由StringBuilder
、StringBuffer
、String
和 实现CharBuffer
)获得。所以你可以简单地做:
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"));
Will output This works with StringBuilders
.
将输出This works with StringBuilders
.
回答by David Ehrmann
I don't want to go down this road because StringBuffer is slower.
我不想走这条路,因为 StringBuffer 速度较慢。
True, but with the usual premature optimization caveat, and more importantly, modern JVMs use escape analysis to remove the StringBuffer/Vector/HashTable locksin certain cases, so once that optimization happens, the performance will be roughly the same.
没错,但有通常的过早优化警告,更重要的是,现代 JVM在某些情况下使用逃逸分析来移除 StringBuffer/Vector/HashTable 锁,因此一旦发生优化,性能将大致相同。
回答by Unihedron
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.
正则表达式不会在CharSequence
内部修改可变参数。正则表达式解析 aCharSequence
返回 a String
,String
结果在哪里。StringBuffer
是一个例外,因为有特殊处理 - 至于StringBuilder
be CharSequence
,您必须使用匹配结果修改它。
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>##代码##</b>"));
}
回答by Audrius Meskauskas
Apache Harmony Matcher source codeseems fully reworkable to be used with StringBuilder
instead of the currently used StringBuffer
, just move to the different package. It seems not dragging a lot of dependences with it. Apache license that is at the start of the file may not be bad even for commercial project.
Apache Harmony Matcher 源代码似乎完全可以重做以StringBuilder
代替当前使用的StringBuffer
,只需移动到不同的包即可。它似乎并没有拖着很多依赖。即使对于商业项目,文件开头的 Apache 许可证也可能不错。
GNU Classpathcode can also be reused but the license is more difficult there (you need to publish your changed version of the Matcher but probably not the rest of your code). Same about the original Sun's implementation that can be found herein the OpenJDK project.
GNU Classpath代码也可以重用,但那里的许可证更困难(您需要发布您更改的 Matcher 版本,但可能不是您的其余代码)。同样对原Sun公司的实现,可以发现这里在OpenJDK项目。