我试图转换的 String \something\到 String \\something\\使用 replaceAll,但我不断得到各种各样的错误。我以为这就是解决办法:
String
\something\
\\something\\
replaceAll
theString.replaceAll("\\", "\\\\");
但这给了以下例外情况:
java.util.regex.PatternSyntaxException: Unexpected internal error near index 1
您需要转义第一个参数中的(转义)反斜杠,因为它是一个正则表达式。Replace (第二个参数-见 Matcher # replaceAll (String))也有反斜杠的特殊含义,所以你必须将它们替换为:
theString.replaceAll("\\\\", "\\\\\\\\");
是的... 当正则表达式编译器看到您给出的模式时,它只看到一个反斜杠(因为 Java 的 lexer 已经将双重反斜杠转换为单一反斜杠)。你需要用 "\\\\"代替 "\\\\",信不信由你!Java 真的需要一个好的原始字符串语法。
"\\\\"
为了避免这种麻烦,可以使用 replace(采用普通字符串)而不是 replaceAll(采用正则表达式)。您仍然需要转义反斜杠,但不是以正则表达式所需的疯狂方式。
replace
String#replaceAll()将参数解释为 正则表达式。\是 都有String和 regex中的转义字符。对于 regex,需要双重转义:
String#replaceAll()
\
regex
string.replaceAll("\\\\", "\\\\\\\\");
但是您不一定需要正则表达式,因为您需要精确的字符替换,而且这里不需要模式。因此,String#replace()应该足够了:
String#replace()
string.replace("\\", "\\\\");
更新 : 根据注释,您似乎希望在 JavaScript 上下文中使用该字符串。您可能最好使用 StringEscapeUtils#escapeEcmaScript()来覆盖更多的字符。
StringEscapeUtils#escapeEcmaScript()
TLDR: 使用 theString = theString.replace("\\", "\\\\");代替。
theString = theString.replace("\\", "\\\\");
replaceAll(target, replacement)对 target使用正则表达式(regex)语法,对 replacement使用部分正则表达式语法。
replaceAll(target, replacement)
target
replacement
问题是,\在 regex 中是特殊字符(它可以像 \d一样用来表示数字) ,在 String Literal 中是特殊字符(它可以像 "\n"一样用来表示行分隔符,或者像 \"一样用来转义通常表示字符串文字结尾的双引号符号)。
\d
"\n"
\"
在这两种情况下,为了创建 \符号,我们可以通过在它前面放置额外的 \(就像我们通过 \"在字符串中转义 ")来 逃跑它(使它成为字面值而不是特殊字符)。
"
因此,对于表示 \符号的 target正则表达式,需要保存 \\,而表示此类文本的字符串文本则需要看起来像 "\\\\"。
\\
所以我们逃脱了两次 \:
"\\"
在 replacement的情况下,\也是特殊的。它允许我们转义其他特殊字符 $,通过 $x符号,允许我们使用部分数据匹配的正则表达式和保持捕获组索引为 x,就像 "012".replaceAll("(\\d)", "$1$1")将匹配每个数字,把它放在捕获组1和 $1$1将取代它的两个副本(它将复制它) ,结果 "001122"。
$
$x
x
"012".replaceAll("(\\d)", "$1$1")
$1$1
"001122"
因此,为了让 replacement表示 \的字面值,我们需要用额外的 \来转义它,这意味着:
但是,因为我们希望 replacement举行 二反斜杠,我们将需要 "\\\\\\\\"(每个 \代表一个 "\\\\")。
"\\\\\\\\"
所以使用 replaceAll的版本可以看起来像
replaceAll("\\\\", "\\\\\\\\");
为了使生活更加简单,Java 提供了工具,可以自动将文本转义为 target和 replacement部分。因此,现在我们只关注字符串,而忘掉正则表达式语法:
replaceAll(Pattern.quote(target), Matcher.quoteReplacement(replacement))
就我们的情况来看
replaceAll(Pattern.quote("\\"), Matcher.quoteReplacement("\\\\"))
如果我们真的不需要正则表达式语法支持,那么就不要涉及 replaceAll。相反,让我们使用 replace。这两种方法都将替换 所有人 target,但是 replace不涉及正则表达式语法。所以你可以简单地写