Java 字符串 ReplaceAll 和 ReplaceFirst 在替换文本的 $ 符号处失败
Posted
技术标签:
【中文标题】Java 字符串 ReplaceAll 和 ReplaceFirst 在替换文本的 $ 符号处失败【英文标题】:Java String ReplaceAll and ReplaceFirst Fails at $ Symbol at Replacement Text 【发布时间】:2012-12-18 15:15:44 【问题描述】:我写了这段代码:
public static void main(String args[]) throws Exception
String template = "The user has spent amount in a day";
String pattern = "amount";
String output = template.replaceAll(pattern, "$ 100");
System.out.println(output);
这就是我运行它时发生的情况:
Exception in thread "main" java.lang.IllegalArgumentException: Illegal group reference
at java.util.regex.Matcher.appendReplacement(Matcher.java:713)
at java.util.regex.Matcher.replaceAll(Matcher.java:813)
at java.lang.String.replaceAll(String.java:2190)
at demo.BugDemo.main(BugDemo.java:16)
Java Result: 1
我正在从文件中读取数据。我应该转义文件数据中的所有$
符号,还是这是一个不必要的过程?有没有其他类或库来处理这种情况?
在替换文本中(不是在正则表达式中)有一个特殊符号有什么问题?
注意事项:
我不想检查每个字符以进行转义。这就是我问这个问题的原因。
我使用的是 Java 6。
【问题讨论】:
试试\\\$
; $ 我相信是一个特殊的字符。
@Telthien:不是 Java 语言。就正则表达式而言,它是。这是你的意思吗? (您的评论不清楚。)
哦,是的,哎呀。将转义改为\\\$
@Telthien:为什么要使用三个反斜杠?它不需要从 Java 的角度转义。
@Telthien 该问题询问模式何时涉及特殊字符,与我的问题完全不同。我的文字中有特殊字符。
【参考方案1】:
String.replaceAll
以正则表达式 matching 模式作为其第一个参数,正则表达式 replacement 模式作为其第二个参数 - 而$
具有特定含义在正则表达式中(在匹配模式和替换模式中,虽然在不同的意义上)。
只需改用String.replace
,我怀疑您的所有问题都会消失。只有当您真正想要通过正则表达式匹配/替换时,您才应该使用replaceAll
- 我认为您在这种情况下不会这样做。
编辑:至于你的问题:
在替换文本中(不是在正则表达式中)有一个特殊符号有什么问题?
replaceAll
的文档再次说明了这一点:
请注意,替换字符串中的反斜杠 (\) 和美元符号 ($) 可能会导致结果与将其视为文字替换字符串时的结果不同;见
Matcher.replaceAll
。如果需要,请使用Matcher.quoteReplacement(java.lang.String)
隐藏这些字符的特殊含义。
因此,如果您想将 匹配 模式视为正则表达式,而不是替换,则使用 Matcher.quoteReplacement
。
【讨论】:
你检查过replaceFirst
的文档吗?是的,它仍然使用正则表达式和替换 patterns。 为什么你要使用replaceAll
或replaceFirst
?
我想用“y”替换第一次出现的“x”,而不是其余的。那么有什么替代方案呢?
@Jus12:听起来你应该问一个新问题,因为这不是这个问题的内容。一种选择是使用indexOf
查找x
,然后使用substring
和连接。可能还有另一种选择 - 很可能有关于此案的问题,但不是 this 问题。
感谢您的回答。另请注意,相同的解释和解决方案适用于 appendReplacement
方法。
@ChristianGosch:引用文档:“请注意,替换字符串中的反斜杠 (\) 和美元符号 ($) 可能会导致结果与将其视为文字替换时不同字符串;参见 Matcher.replaceAll。”这对我来说似乎很清楚。 (它不会将其视为正则表达式;它的处理方式与处理正则表达式替换中的替换字符串的方式相同。)【参考方案2】:
在替换字符串中,$
是一个特殊字符:它用于从要替换的模式中获取匹配的组。你可以阅读更多关于它的信息here。
要解决此问题,您可以引用替换字符串以从 $
字符中删除所有特殊含义:
import java.util.regex.Matcher;
// ...
String output = template.replaceAll(pattern, Matcher.quoteReplacement("$ 100"));
【讨论】:
为什么要这样做而不是仅仅使用不使用正则表达式的 API? @JonSkeet 好点,如果不需要 replaceAll 你的答案会更好。 @kamaci 替换文本不是正则表达式,但它仍然很特别。$
字符在替换文本中是特殊的。阅读此链接了解更多信息:docs.oracle.com/javase/6/docs/api/java/lang/…
@CoryKendall 我应该将 Matcher.quoteReplacement 用于 replaceFirst 还是有其他方法?【参考方案3】:
可以处理特殊字符$
的方法很简单。
检查以下示例
public static void main(String args[])
String test ="Other company in $ city ";
String test2 ="This is test company ";
try
test2= test2.replaceFirst(java.util.regex.Pattern.quote("test"), Matcher.quoteReplacement(test));
System.out.println(test2);
test2= test2.replaceAll(java.util.regex.Pattern.quote("test"), Matcher.quoteReplacement(test));
System.out.println(test2);
catch(Exception e)
e.printStackTrace();
输出:
This is Other company in $ city company
This is Other company in $ city company
【讨论】:
【参考方案4】:试试这个
String template = "The user has spent amount in a day";
String pattern = "amount";
String output = template.replaceAll(pattern, "\\$ 100");
System.out.println(output);
【讨论】:
【参考方案5】:$
用于指定替换组的符号。你需要逃避它:
String output = template.replaceAll(pattern, "\\$ 100");
【讨论】:
以上是关于Java 字符串 ReplaceAll 和 ReplaceFirst 在替换文本的 $ 符号处失败的主要内容,如果未能解决你的问题,请参考以下文章