为什么Java replaceAll() 使用正则表达式需要在前面加“\\”?

Why Java replaceAll() using regular expression need to add "\\" at front?

对于输入字符串 id,我想执行如下 4 个步骤:

  1. 删除所有非小写字母、数字、“-”、“_”、“.”
  2. 如果是“.”是多个连续的,换成单个“.” (例如:他......llo -> he.llo)
  3. 如果字符串以“.”开头,将其删除。
  4. 如果字符串以“.”结尾,将其删除。

这是我的第 4 行代码:

id = id.replaceAll("[^" + "a-z" + "0-9" + "-" + "_" + "." + "]", "");
id = id.replaceAll(".{2,}",".");
id = id.replaceAll("^.","");
id = id.replaceAll(".$","");

我发现规则 2 的 return 是“.” (例如:他...llo -> 。) 规则 3,4 将删除不是“.”的字符串。

所以我将代码修改为:

id = id.replaceAll("[^" + "a-z" + "0-9" + "-" + "_" + "." + "]", "");
id = id.replaceAll("\.{2,}",".");
id = id.replaceAll("\^.","");
id = id.replaceAll("\.$","");

而且效果很好。 我只是不明白。那个正则表达式在使用之前需要加两次“\”吗? 如果是正确的,为什么规则 1 可以正常工作?谁能具体帮我解答一下? 最后,我想知道我可以同时编码规则 3 和规则 4 吗?喜欢使用 && 到 ?

  • . 在正则表达式中表示“匹配任何单个字符”
  • \. 在正则表达式中表示“匹配单个 dot/period/full-stop 字符”。另一种写法是 [.],它具有相同的最终结果,但在语义上有所不同(我不确定这是否会对生成的代码匹配表达式产生负面影响)
  • [abc.] 在正则表达式中表示“匹配必须是 'a' 或 'b' 或 'c' 或 '.' 的单个字符”([^…] 反转含义:匹配任何 不是 ) 的字符。注意:- 在字符 class 中有特殊含义,因此如果要专门匹配连字符,请确保始终将其放在最前面或最后。

至于为什么要重复反斜杠:Java本身使用反斜杠来转义字符串中的字符。要将文字反斜杠作为字符串的一部分,您必须转义反斜杠本身:"\" 是一个包含单个反斜杠字符的字符串("\" 是 Java 中的语法错误,因为反斜杠转义后面的引号,即字符串永远不会终止)。

为了将您的逻辑减少到两个 replaceAll 调用,我建议更改您的调用顺序,然后使用 | 运算符加入您的表达式作为替代:

id = id.replaceAll(".+", ".") // fold all dots
        .replaceAll("[^a-z0-9_.-]|^\.|\.$", "");