java正则表达式
在学习java正则表达式时,遇到三个问题。
1、java字符串和正则模式的字符串很不清楚
2、正则中有捕获组的概念,并且还能对捕获后的组进行字符串替换,即appendreplacement(stringbuffer sb, string replacement)方法的原理不清楚
3、为什么在调用appendreplacement(stringbuffer sb, string replacement)方法之前需要对replacement中的"\"和"$"字符进行转义。
java正则表达式一般是对于字符串的操作,个人理解在正则表达式中,字符串有三个基本的概念:
第一,代码字符串:写在java文件中的字符串。
第二,内存字符串:代码字符串在内存中的形式。
第三,正则模式字符串:由pattern编译内存字符串形成的正则模式字符串。
比如在java代码中表示一个"\$"字符串,应该这样写
Java代码
string code = "\\$"; system.out.println("code: " + code);
输出结果 code: \$
因为在java代码中"\"表示转义字符,所以第一个"\"表示要转义后面的内容。在内存中,code内存字符串形式就是"\$"。
现在想写一个正则表达式匹配字符串"\$",代码如下:
Java代码
string code="\\$"; system.out.println("code: " + code); string patternstring ="\\\\\\$"; pattern pattern = pattern.compile(patternstring); matcher matcher = pattern.matcher(code); while(matcher.find()) { system.out.println("matcher:" + matcher.group()); }
输出结果 code:\$
matcher:\$
为什么匹配模式的java代码字符串是"\\\\\\$"。code在内存中形式是:\$,那正则模式字符串也应该是\$,在编译为模式字符串前的内存字符串应该是\\\$。正则模式字符串的第一个"\",在内存中应该是"\\"(正则模式中的\表示转义),而$在内存中应该是\$(正则模式串中$表示空白字符,所以需要转义),所以模式字符串在编译前在内存中的形式应该\\\$。内存的\\\$,再转换为java代码,应该是[color=red]"\\\\\\$"
在使用正则时经常用到捕获组,对于捕获到的组进行字符串替换,需要用到appendreplacement(stringbuffer sb, string replacement)方法。该方法对于第二个参数替换的字符串有特殊要求,如果replacement里有"\"字符串和"$"字符串则必须要进行转义。为什么了?可以看看源代码replacement的源码:
[/color]
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;
补充:软件开发 , Java ,