正则表达式匹配正确也报错?

来源:互联网 发布:bp网络和神经网络区别 编辑:程序博客网 时间:2024/04/30 20:54

      正则表达式,我想大家都不陌生。Java有,C#有,JavaScript有,其他语言也有,大致的匹配规则都很相似。如果用过正则表达式的开发人员,都觉得这个是个好东西。不过本人在一次获取一段字符串里的数字时遇到一个奇怪的问题。代码如下:

 

 

100,300,400,500,600,700,800,900,
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 32
    at java.lang.StringBuffer.charAt(StringBuffer.java:162)
    at java.util.regex.Pattern$BmpCharProperty.match(Pattern.java:3366)
    at java.util.regex.Pattern$Curly.match0(Pattern.java:3760)
    at java.util.regex.Pattern$Curly.match(Pattern.java:3744)
    at java.util.regex.Pattern$Start.match(Pattern.java:3055)
    at java.util.regex.Matcher.search(Matcher.java:1105)
    at java.util.regex.Matcher.find(Matcher.java:535)
    at test.PatternTest.main(PatternTest.java:18)

 

得到的结果是这个。开始我觉得好奇怪,为什么匹配出来了,回报数组下标越界呢?我试着把字符序列a用toString()方法改为字符串放到matcher中去匹配,运行以后能匹配而且没有报错。怪了,难道说正则匹配的字符序列不能改变么?于是我查了文档,发现matcher中的参数是CharSequence 类型的,然后我又找到描述这个接口的文档,上面说到:

       “CharSequencechar 值的一个可读序列。此接口对许多不同种类的 char 序列提供统一的只读访问。”

      这么说这个字符序列真的不能改变?于是我又运行了如下代码:

 

 

结果输出的是:100,200,300,400,500,600,700,800,900,100,

这我就纳闷了,不是说不能改变吗,怎么加上一个不报错呢?其实我也不知道是不是我理解错误。于是又试验了如下代码:

 

 

结果输入是:100,300,400,500,600,700,800,900,100, 并且没有报错,看来真的不是改变字符序列,那么为什么对a用delete方法会报错呢?我猜想可能是每次正则匹配都会去检查那个需要匹配的字符序列的长度有没有改变。那我就来验证一下,继续贴代码

 

 

结果输出是:两行100,300,400,500,600,700,800,900,200,和i=9,由此说明,matcher方法每一次匹配都会去检查被匹配序列的长度,如果长度小于第一次匹配时的字符序列长度,则会报错。而且i=9也表示,matcher只匹配了9次,即使append两个200,也只会留下一个,因为第一次num与匹配值相同是,把100后面的200删除了,同时在字符序列最后添加了200,等到匹配到第九次,也是最后一个数字时,删除200,同时再在末尾添加一个200。此时matcher不再匹配,所以不会导致while无限循环。

      所以可以得出结论:正则表达式在匹配取值时,每一次匹配都会检查原序列长度是否有减少,如果有减少则报错,并且匹配的字符长度也是不可变的,此长度即为在创建匹配器时所输入的字符序列的长度。

      第一次发文章,代码编辑器用得还不太习惯,有点囧。。。这些都是自己实验得到的结论,希望大家围观,如有错,还请各位指出,大家一起进步。