在匹配涉及美元符号的子模式时,我遇到了一个问题。例如,考虑以下文本块:
(en $) foo
oof ($).
ofo (env. 80 $US)
我正在使用以下正则表达式:
Pattern p = Pattern.compile(
"\\([\\p{InARABIC}\\s]+\\)|\\([\\p{InBasic_Latin}\\s?\\$]+\\)|\\)([\\p{InARABIC}\\s]+)\\(",
Pattern.CASE_INSENSITIVE);
public String replace(String text) {
Matcher m = p.matcher(text);
String replacement = m.replaceAll(match -> {
if (m.group(1) == null) {
return m.group();
} else {
return "(" + match.group(1) + ")";
}
});
return replacement;
}
但不能匹配包含$
答案 0 :(得分:2)
此代码类似于replaceAll(regex, replacement)
。问题是$
不仅在 regex 参数中是特殊的,而且在 replacement 中也可以用作{{1 }}(其中$x
是组ID)或x
(如果您的正则表达式具有${groupName}
)。
这使我们可以编写类似的代码
(?<groupName>subregex)
它将用两个副本替换每个字符,因为每个字符将由String doubled = "abc".replaceAll(".", "$0$0");
System.out.println(doubled); //prints: aabbcc
匹配并放在组0中,因此.
表示该匹配字符的两次重复。
但是在您的情况下,您的$0$0
中有$
,因此当它与之匹配时,您将其替换为自己,因此您将使用text
替换任何内容有关组ID的信息(或组名),结果为$
。
解决方案是将IllegalArgumentException: Illegal group reference
替换为替换部分。您可以使用$
手动完成此操作,但最好使用为此目的设计的方法Matcher#quoteReplacement
(以防正则表达式会演变而您需要转义更多的事情,该方法应与正则表达式引擎,以后可以为您省些麻烦)
所以尝试将代码更改为
\