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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-01 01:48:40  来源:igfitidea点击:

replaceAll for StringBuilder with regex support?

javaregexstringstringbuilder

提问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.replaceAllis just a convenience method for Matcher.replaceAll. Matcheris the "actual" way to use regex in Java and is allows for a lot more sophisticated use cases.

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

Moreover, anything that can be done with regex methods on Stringcan be done with similar methods on a Matcher. The beauty is, that Matchers work with more than just Strings: Matchers can be obtained for any CharSequence(an interface, which is implemented by StringBuilder, StringBuffer, Stringand CharBuffer). So you can simply do:

此外,凡是能与正则表达式的方法上进行String可以用一个类似的方法来完成Matcher。美妙之处在于,这Matcher不仅仅是Strings:Matchers 可以为 any CharSequence(一个接口,由StringBuilderStringBufferString和 实现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.

Working demo.

工作演示。

回答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 CharSequenceinternally. Regex parses a CharSequenceto return a String, where Stringis the result. StringBufferis an exception as there is special handling - as for StringBuilderbeing CharSequence, you have to modify it with a match result.

正则表达式不会在CharSequence内部修改可变参数。正则表达式解析 aCharSequence返回 a StringString结果在哪里。StringBuffer是一个例外,因为有特殊处理 - 至于StringBuilderbe 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>"));
}

View a test code demo!

查看测试代码演示!

回答by Audrius Meskauskas

Apache Harmony Matcher source codeseems fully reworkable to be used with StringBuilderinstead 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项目。