It turns out that the second parameter of String.replaceAll is a not an ordinary string but a replacement string, as defined in the java.util.regex specification [Java-API]. A backslash appearing in a replacement string escapes the following character, causing it to be treated literally. When you run the program on Windows, the replacement string is a lone backslash character, which is invalid 可以这么做:System.out.println("java.lang.String".replaceAll(Pattern.quote("."),Matcher.quoteReplacement("\\")));参考:java puzzlers,Puzzle 21: What's My Class, Take 2
看看 java源代码的实现对\和$都有特殊的处理 public Matcher appendReplacement(StringBuffer sb, String replacement) { // If no match, return error if (first < 0) throw new IllegalStateException("No match available"); // Process substitution string to replace group references with groups int cursor = 0; String s = replacement; StringBuffer result = new StringBuffer(); while (cursor < replacement.length()) { char nextChar = replacement.charAt(cursor); if (nextChar == '\\') { cursor++; nextChar = replacement.charAt(cursor); result.append(nextChar); cursor++; } else if (nextChar == '$') { // Skip past $ cursor++; // The first number is always a group int refNum = (int)replacement.charAt(cursor) - '0'; if ((refNum < 0)||(refNum > 9)) throw new IllegalArgumentException( "Illegal group reference"); cursor++; // Capture the largest legal group string boolean done = false; while (!done) { if (cursor >= replacement.length()) { break; } int nextDigit = replacement.charAt(cursor) - '0'; if ((nextDigit < 0)||(nextDigit > 9)) { // not a number break; } int newRefNum = (refNum * 10) + nextDigit; if (groupCount() < newRefNum) { done = true; } else { refNum = newRefNum; cursor++; } } // Append group if (group(refNum) != null) result.append(group(refNum)); } else { result.append(nextChar); cursor++; } }
String的replaceAll方法实际就是用的Mather的replaceAll方法. 而Mather的replaceAll方法有这样一段注释 * <p> Note that backslashes (<tt>\</tt>) and dollar signs (<tt>$</tt>) in * the replacement string may cause the results to be different than if it * were being treated as a literal replacement string. Dollar signs may be * treated as references to captured subsequences as described above, and * backslashes are used to escape literal characters in the replacement * string.你可以直接使用String.replace("[.]","\\"),结果就正确了. 因为这个replace就是用的如一楼所说的Matcher.quoteReplacement("\\")
可以这么做:System.out.println("java.lang.String".replaceAll(Pattern.quote("."),Matcher.quoteReplacement("\\")));参考:java puzzlers,Puzzle 21: What's My Class, Take 2
public Matcher appendReplacement(StringBuffer sb, String replacement) { // If no match, return error
if (first < 0)
throw new IllegalStateException("No match available"); // Process substitution string to replace group references with groups
int cursor = 0;
String s = replacement;
StringBuffer result = new StringBuffer(); while (cursor < replacement.length()) {
char nextChar = replacement.charAt(cursor);
if (nextChar == '\\') {
cursor++;
nextChar = replacement.charAt(cursor);
result.append(nextChar);
cursor++;
} else if (nextChar == '$') {
// Skip past $
cursor++; // The first number is always a group
int refNum = (int)replacement.charAt(cursor) - '0';
if ((refNum < 0)||(refNum > 9))
throw new IllegalArgumentException(
"Illegal group reference");
cursor++; // Capture the largest legal group string
boolean done = false;
while (!done) {
if (cursor >= replacement.length()) {
break;
}
int nextDigit = replacement.charAt(cursor) - '0';
if ((nextDigit < 0)||(nextDigit > 9)) { // not a number
break;
}
int newRefNum = (refNum * 10) + nextDigit;
if (groupCount() < newRefNum) {
done = true;
} else {
refNum = newRefNum;
cursor++;
}
} // Append group
if (group(refNum) != null)
result.append(group(refNum));
} else {
result.append(nextChar);
cursor++;
}
}
replaceAll
public String replaceAll(String regex,
String replacement)使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。
调用此方法的 str.replaceAll(regex, repl) 形式与以下表达式产生的结果完全相同: Pattern.compile(regex).matcher(str).replaceAll(repl)
注意,在替代字符串中使用反斜杠 (\) 和美元符号 ($) 与将其视为字面值替代字符串所得的结果可能不同;请参阅 Matcher.replaceAll。如有需要,可使用 Matcher.quoteReplacement(java.lang.String) 取消这些字符的特殊含义。
参数:
regex - 用来匹配此字符串的正则表达式
replacement - 用来替换每个匹配项的字符串
返回:
所得 String
抛出:
PatternSyntaxException - 如果正则表达式的语法无效
从以下版本开始:
1.4
另请参见:
Pattern--------------------------------------------------------------------------------
"java.lang.String".replaceAll("[.]",Matcher.quoteReplacement("$"));"java.lang.String".replaceAll("[.]",Matcher.quoteReplacement("\\"));
而Mather的replaceAll方法有这样一段注释 * <p> Note that backslashes (<tt>\</tt>) and dollar signs (<tt>$</tt>) in
* the replacement string may cause the results to be different than if it
* were being treated as a literal replacement string. Dollar signs may be
* treated as references to captured subsequences as described above, and
* backslashes are used to escape literal characters in the replacement
* string.你可以直接使用String.replace("[.]","\\"),结果就正确了.
因为这个replace就是用的如一楼所说的Matcher.quoteReplacement("\\")
我忘记把[]去掉了
应该是System.out.println("java.lang.String".replace(".", "\\"));之前不行是因为没匹配上[.]