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:usetheString=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的答案!