我试图使用replaceAll
将String
\something\
转换为String
\\something\\
,但我一直收到各种错误。我原以为这是解决方案:
theString.replaceAll("\\", "\\\\");
但是这会导致以下异常:
java.util.regex.PatternSyntaxException: Unexpected internal error near index 1
我试图使用replaceAll
将String
\something\
转换为String
\\something\\
,但我一直收到各种错误。我原以为这是解决方案:
theString.replaceAll("\\", "\\\\");
但是这会导致以下异常:
java.util.regex.PatternSyntaxException: Unexpected internal error near index 1
String#replaceAll()
方法将参数解释为正则表达式。在 String
和 regex
中,\
都是转义字符。如果要在正则表达式中使用它,需要进行双重转义。
string.replaceAll("\\\\", "\\\\\\\\");
但是您不一定需要使用正则表达式,因为您想要进行逐个字符的精确替换,并且在此处不需要模式。 因此,String#replace()
应该就足够了:
string.replace("\\", "\\\\");
更新:根据评论,您似乎想在JavaScript上下文中使用该字符串。建议您最好使用StringEscapeUtils#escapeEcmaScript()
,以覆盖更多字符。TLDR:请使用 theString = theString.replace("\\", "\\\\");
。
replaceAll(target, replacement)
方法在处理 target
和部分 replacement
参数时使用正则表达式(regex)语法。
问题在于,在正则表达式中和字符串文字中,\
都是特殊字符(例如,可以使用 \d
表示数字,在字符串文字中可以使用 "\n"
表示行分隔符,或者 \"
来转义双引号符号,否则会表示字符串文字的结尾)。
在这两种情况下,我们可以通过在其前面放置额外的 \
来将其 转义(使其成为特定意义之外的字面值),从而创建 \
符号(例如,我们可以通过 \"
转义字符串文字中的 "
)。
因此,对于表示 \
符号的 target
正则表达式,需要使用 \\
,表示此文本的字符串字面值需要看起来像 "\\\\"
。
所以我们将 \
转义了两次:
\\
"\\\\"
(每个 \
都用 "\\"
表示)。对于 replacement
参数,\
也是特殊字符。它允许我们转义其他特殊字符 $
,通过 $x
表示法,使用被正则表达式匹配并由索引为 x
的捕获组持有的部分数据,例如:"012".replaceAll("(\\d)", "$1$1")
将匹配每个数字,将其放置在捕获组 1 中,并使用 $1$1
将其替换为两个副本(即复制它),结果为 "001122"
。
因此,为让 replacement
表示 \
字面值,我们需要使用附加的 \
进行转义,这意味着:
\\
\\
的字符串字面值如 "\\\\"
。但是,由于我们希望 replacement
拥有 两个 反斜杠,因此我们需要使用 "\\\\\\\\"
(每个 \
都用一个 "\\\\"
表示)。
因此,使用 replaceAll
的版本可以如下所示:
replaceAll("\\\\", "\\\\\\\\");
replaceAll
更简单为了使我们的生活更加轻松,Java提供了工具自动将文本转义为目标
和替换
部分。因此,现在我们可以只关注字符串,而不必再考虑正则表达式的语法:
replaceAll(Pattern.quote(target), Matcher.quoteReplacement(replacement))
在我们的情况下可能看起来像
replaceAll(Pattern.quote("\\"), Matcher.quoteReplacement("\\\\"))
replace
如果我们不需要正则表达式语法支持,那就完全不用涉及replaceAll
。相反,我们可以使用replace
。两种方法都会替换所有target
,但replace
不涉及正则表达式语法。所以你只需简单地写成:
theString = theString.replace("\\", "\\\\");
replace
(需要一个普通字符串)而不是replaceAll
(需要一个正则表达式)。您仍然需要转义反斜杠,但不需要像正则表达式那样进行复杂的转义。您需要转义第一个参数中的(转义)反斜杠,因为它是一个正则表达式。替换(第二个参数-参见Matcher#replaceAll(String))也有其特殊含义的反斜杠,所以您需要将其替换为:
theString.replaceAll("\\\\", "\\\\\\\\");
是的...当正则表达式编译器看到您给出的模式时,它只看到一个反斜杠(因为Java的词法分析器将双反斜杠转换为单个反斜杠)。你需要用"\\\\"
替换"\\\\"
,信不信由你! Java真的需要一个好的原始字符串语法。
String#replaceAll()
,您可以使用 Matcher#quoteReplacement() 引用替换字符串:theString.replaceAll("\\", Matcher.quoteReplacement("\\\\"));
。请注意不要改变原始意思。 - phse