模式涉及美元符号($)时的正则表达式

时间:2019-04-23 10:18:28

标签: java regex

在匹配涉及美元符号的子模式时,我遇到了一个问题。例如,考虑以下文本块:

(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;
    }

但不能匹配包含$

的文本

1 个答案:

答案 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(以防正则表达式会演变而您需要转义更多的事情,该方法应与正则表达式引擎,以后可以为您省些麻烦)

所以尝试将代码更改为

\