String 方法 replaceFirst 、replaceAll 和 No group Exception

今天被OA的一个问题搞得很无语,m.appendReplacement(sb, bodyArr[j]);报索引溢出的异常,找了半天的原因。后来几经周折才连接正式系统,跟踪里面的异常。
结果发现是String的使用过程中出现节点越界
java.lang.IndexOutOfBoundsException: No group 2
at java.util.regex.Matcher.group(Matcher.java:355)
at java.util.regex.Matcher.appendReplacement(Matcher.java:585)
at java.util.regex.Matcher.replaceFirst(Matcher.java:701)
at java.lang.String.replaceFirst(String.java:1630)
当时我就纳闷,contentStr.replaceFirst(fromStr, toStr) 这方法中处理的内容会越界?why?
contentStr,fromStr, toStr在项目中都是不可能为null,即便为null值那也应该是抛NullpointException异常才对;又或者压根没替换,那也不会有异常啊......
说实话,当时的我压根不会想到是JDK API本身的问题,那些代码逻辑都是几经磨练和测试okay后才成为了API的,肯定是我写代码的某些地方出了问题。可就是找不出破绽来。
只好到google谷歌了一下,结果发现有网友留言说此种情况算是Matcher的一个bug来的。
晕,之前居然老以为是自己代码出了漏洞。看来今后不能那么迷信权威了。
结果那网友说了是Matcher做替换时replaceAll 或者 replaceFirst 时,会对字符串中的“$”符号敏感,出现IndexOutOfBoundsException的问题,如上面的contentStr.replaceFirst(fromStr, "xx$xx")就会出错。摘录下网友的留言 in blue:
You have to track through the documentation quite carefully to discover that the characters \ and $ have a special 
meaning in the replacement string.  It could be helpful to copy this sentence from Matcher.replaceAll into all 
of String.replaceFirst, String.replaceAll, and Matcher.replaceFirst:

"Note that backslashes (\) and dollar signs ($) in the replacement string may cause the results to be different than 
if it were being treated as a literal replacement string."
呵呵,这才想起似乎之前测试数据库中都没有含“$”符号的数据,偏巧正式数据库中有这些记录。 额的神!难怪之前测不出来。
不过总算知道问题根源了,呵呵,强行过滤Str中的“$”符号,替换后再还原它的“$”面目。
搞定!!!

你可能感兴趣的:(java,jdk,Google,J#,sun)