如何在Java中没有正则表达式的情况下只替换一次字符串?

pol*_*lot 22 java string

我需要用一个更大的字符串替换一个动态子字符串,但只需要一次(即第一次匹配).String类仅提供replace(),它替换子字符串的所有实例; 有一个replaceFirst()方法,但它只需要regexp而不是常规字符串.我对使用正则表达式有两个顾虑:

1)我的子串是动态的,所以可能包含奇怪的字符,这些字符在正则表达式中表示其他东西,我不想处理字符转义.

2)这种替换经常发生,我不确定使用正则表达式是否会影响性能.由于正则表达式本身是动态的,我无法预先编译正则表达式!

我必须在这里遗漏一些东西,因为在我看来这是一个非常基本的东西......是否有一个replaceFirst方法在java franework中的其他地方使用常规字符串?

Dan*_*ber 27

您应该使用已经过测试并且文档齐全的库来支持编写自己的代码!

StringUtils.replaceOnce("aba", "a", "")    = "ba"
Run Code Online (Sandbox Code Playgroud)

StringUtils类是Apache的百科全书Lang3封装,可以在Maven中导入这样的:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.8.1</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)


Ben*_*wee 20

劳伦斯建议,你可以Pattern.quote像这样使用:

newString = string.replaceFirst(Pattern.quote(substring), replacement);
Run Code Online (Sandbox Code Playgroud)

这会创建一个与子字符串字面匹配的新正则表达式.另一种方法是简单地将子字符串编译为文字正则表达式,如下所示:

newString = Pattern.compile(substring, Pattern.LITERAL).
        matcher(string).replaceFirst(replacement);
Run Code Online (Sandbox Code Playgroud)

这可能稍微有点效率,但也不太清楚.

您也可以手动执行此操作,因为您只想替换第一个匹配项.但是正则表达式非常有效,所以不要过早优化!

  • 这没有提到替换也需要引用。 (2认同)

Ale*_*lli 12

使用bigString.indexof(smallString)来获取小字符串中第一次出现的索引在大一个(或-1,如果没有,在这种情况下,你就大功告成了).然后,用来bigString.substring在比赛前后获得大弦的碎片,最后concat将这些碎片放回到一起,然后将它们放在中间.

  • 阿门 - 这个答案展示了s/w开发的一个关键原则:仅仅因为你有一个工具,并不意味着你必须使用它.我不能告诉你有多少次我看到中级程序员排序列表以找到最小的元素. (4认同)
  • 这是一个很好的评论.但请注意,此手动方法需要几行代码,这可能需要注释和单元测试以避免错误.使用单行`replaceFirst'调用更清晰,更不容易出错,即使它在运行时也可能更慢.不要过早优化. (2认同)

use*_*094 6

确保也替换\s$s更换.这可能是你想要的,因为你不能有任何子组与你()的被删除).

newStr = str.replaceFirst(Pattern.quote(target), Matcher.quoteReplacement(replacement));
Run Code Online (Sandbox Code Playgroud)