第一个坑
JAVA的转义字符使用经常会有一些小坑,反正我是掉进去了,来看代码吧?
//输出true
System.out.println("id=$id".contains("$id"));
//输出id=$id
System.out.println("id=$id".replaceAll("$id","4"));
//输出id=4
System.out.println("id=$id".replaceAll("\\$id","4"));
复制代码
contains和replaceAll的逻辑并不一样,contains不用转义就可以识别,而replaceAll是需要转义的。
第二个坑
上例中,你发现contains不用转义,是吧,但有时候还是需要转义的,并且replaceAll需要双倍转义,看代码
//输出true,需要转义
System.out.println("d:\\Document".contains("\\"));
//输出d:/Document,需要双倍转义
System.out.println("d:\\Document".replaceAll("\\\\", "/"));
复制代码
原理分析
\\
是转义字符,在java字符串中代表\
,repleaseAll接收的第一个参数是正则表达式,需要输入双倍\\\\
来表示\\
。
$
在字符串中可以直接使用,所以contains中可以直接使用使用。$
的正则替换需要使用\$
。
如下JDK所言,还有一个办法是使用quoteReplacement。
//输出d:/Document
System.out.println("d:\\Document".replaceAll(Matcher.quoteReplacement("\\"),"/"));
//输出id=4
System.out.println("id=$id".replaceAll(Matcher.quoteReplacement("$id"),"4"));
复制代码
附JDK说明
JDK中replaceAll的解释,接收的第一个参数是表达式,并且\
和 $
是比较特殊的。
/**
*<p>
* Note that backslashes ({@code \}) and dollar signs ({@code $}) in the
* replacement string may cause the results to be different than if it were
* being treated as a literal replacement string; see
* {@link java.util.regex.Matcher#replaceAll Matcher.replaceAll}.
* Use {@link java.util.regex.Matcher#quoteReplacement} to suppress the special
* meaning of these characters, if desired.
*
* @param regex
* the regular expression to which this string is to be matched
* @param replacement
* the string to be substituted for each match
*
* @since 1.4
*/
public String replaceAll(String regex, String replacement) {
return Pattern.compile(regex).matcher(this).replaceAll(replacement);
}
复制代码
JDK中contains的解释,接收的是字符串
/**
* Returns true if and only if this string contains the specified
* sequence of char values.
*
* @param s the sequence to search for
* @return true if this string contains {@code s}, false otherwise
* @since 1.5
*/
public boolean contains(CharSequence s) {
return indexOf(s.toString()) >= 0;
}
复制代码