Java String.replaceAll用双反斜杠替换所有单反斜杠

Java String.replaceAll用双反斜杠替换所有单反斜杠,java,escaping,backslash,replaceall,Java,Escaping,Backslash,Replaceall,我试图使用replaceAll将字符串\something\转换为字符串\\something\\,但我不断收到各种错误。我认为这就是解决办法: theString.replaceAll("\\", "\\\\"); 但这就产生了以下例外情况: java.util.regex.PatternSyntaxException: Unexpected internal error near index 1 您需要在第一个参数中转义(转义)反斜杠,因为它是一个正则表达式。替换(第二个参数-请参阅)也

我试图使用
replaceAll
字符串
\something\转换为
字符串
\\something\\,但我不断收到各种错误。我认为这就是解决办法:

theString.replaceAll("\\", "\\\\");
但这就产生了以下例外情况:

java.util.regex.PatternSyntaxException: Unexpected internal error near index 1
您需要在第一个参数中转义(转义)反斜杠,因为它是一个正则表达式。替换(第二个参数-请参阅)也有反斜杠的特殊含义,因此您必须将其替换为:

theString.replaceAll("\\\\", "\\\\\\\\");

是的。。。当正则表达式编译器看到您给定的模式时,它只看到一个反斜杠(因为Java的lexer已经将双反斜杠变成了单反斜杠)。你需要用
“\\\\”
替换
“\\\\”
,信不信由你!Java确实需要一个好的原始字符串语法。

为了避免这种麻烦,可以使用
replace
(它需要一个普通字符串)而不是
replaceAll
(它需要一个正则表达式)。您仍然需要避开反斜杠,但不能像正则表达式那样随意使用。

将参数解释为反斜杠。
\
字符串和
正则表达式中的转义字符。您需要对正则表达式进行双重转义:

string.replaceAll("\\\\", "\\\\\\\\");
但这并不一定需要正则表达式,因为您需要一个字符一个字符的替换,并且这里不需要模式。这样就足够了:

string.replace("\\", "\\\\");


更新:根据注释,您似乎希望在JavaScript上下文中使用该字符串。您最好使用替换来覆盖更多字符。

TLDR:use
theString=theString.replace(“\\”,“\\\”取而代之


问题
replaceAll(target,replacement)
target
使用正则表达式(regex)语法,部分用于
replacement

问题是,
\
在正则表达式中是特殊字符(它可以像
\d
一样用来表示数字),在字符串文字中是特殊字符(它可以像
“\n”
一样用来表示行分隔符或
\“
用来转义通常表示字符串文字结尾的双引号符号)

在这两种情况下,要创建
\
符号,我们可以通过在其前面放置额外的
\
来对其进行转义(使其成为文字而不是特殊字符)(就像我们通过
\
以字符串文字转义

因此,对于
target
regex,表示
\
的符号需要保持
\
,而表示此类文本的字符串文字需要看起来像
“\\\\”

所以我们逃过了两次
\

  • 一旦进入正则表达式
    \\
  • 一旦进入字符串文字
    “\\\\”
    (每个
    \
    表示为
    “\\\”
replacement
的情况下,
\
也很特殊。它允许我们转义其他特殊字符
$
,它通过
$x
符号,允许我们使用正则表达式匹配的部分数据,并通过捕获索引为
x
的组来保存,如
“012”。replaceAll(“(\\d)”,“$1$1”)
将匹配每个数字,将其放在捕获组1中,
$1$1
将用其两个副本替换它(它将复制它),从而产生
“001122”

同样,为了让
replacement
表示
\
文字,我们需要用额外的
\
对其进行转义,这意味着:

  • 替换必须包含两个反斜杠字符
    \\
  • 表示
    \\
    的字符串文字看起来像
    “\\\\”
但是,由于我们希望
替换
保留两个反斜杠,因此我们需要
“\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/code>(每个
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

因此,带有
replaceAll
的版本可以如下所示

replaceAll("\\\\", "\\\\\\\\");
replaceAll(Pattern.quote("\\"), Matcher.quoteReplacement("\\\\"))
更简单的方法 为了简化操作,Java提供了一些工具,可以自动将文本转义为
target
replacement
部分。因此,现在我们可以只关注字符串,而不用考虑正则表达式语法:

replaceAll(Pattern.quote(target), Matcher.quoteReplacement(replacement))
在我们的例子中,它看起来像

replaceAll("\\\\", "\\\\\\\\");
replaceAll(Pattern.quote("\\"), Matcher.quoteReplacement("\\\\"))
更好 如果我们真的不需要正则表达式语法支持,那么就不要使用
replaceAll
。而是使用
replace
。这两种方法都将替换all
target
s,但是
replace
不涉及正则表达式语法。因此,您可以简单地编写

theString = theString.replace("\\", "\\\\");

实际上,它是在JavaScript AST中使用的,应该转换回源代码。您的解决方案可以工作。谢谢!如果您想使用
String\replaceAll()
无论如何,您可以用以下内容引用替换字符串:
theString.replaceAll(\\”,Matcher.quoteReplacement(\\\);
Matcher.quoteReplacement(…)这是一个好方法!请看Pshemo的答案!