问:如何写正则表达式,去只匹配固定位置的字符串?如匹配形如123abc789中的第四到第六位的字符,即只匹配其中的abc?

答:

解法一:.{3}abc

说明:先匹配任意3个字符,然后后面跟abc字符的字符串。

下图可见,确实匹配到了字符abc, 但也匹配到之前的字符123,同时还匹配到了多个地方如defabc和456abc,即多次匹配。故不满足问题要求。

分析:这里abc被匹配的位置可以到处乱窜。

正则检验以固定字符串结尾java 正则包含指定字符串_bc

解法二:^.{3}abc

说明:基于解法一的教训,很容易想到正则中限定字符开始的语法^,让其开头必须满足条件,这样只能匹配一次。 匹配开头任意3个字符,然后后面跟abc字符的字符串。

下图可见,确实匹配到了第四到第六位的字符abc, 但也匹配到之前的字符123。故不满足问题要求。

正则检验以固定字符串结尾java 正则包含指定字符串_元字符_02

 

解法三:(?<=^.{3})abc

说明:基于解法一的弊端——多次匹配,且每次匹配内容超过指定宽度;基于解法二的弊端——一次匹配,且此次匹配内容超过指定宽度。

如果能让真正要匹配的abc前面的内容不作为最终匹配结果,那不就可以了吗?

零宽断言!

exp1(?=exp2)exp3

exp1(?<=exp2)exp3

exp1(?!exp2)exp3

exp1(?<!exp2)exp3

以上(?)内的表达式exp2都不会作为最终匹配结果返回,只是作为判断条件。

匹配开头任意3个字符,以此作为判断条件即断言,而开头的任意3个字符,又不作为最后匹配的实际宽度即零宽。然后后面跟abc字符的字符串,最后只匹配abc字符串即可。

补充说明:解法二中的^以及$或\b等都是正则的断言元字符。但他们都不是零宽,所以导致可以限定匹配的结果只有一次,但匹配内容超过宽度。解法三正好是断言元字符和零宽断言的结合。

正则检验以固定字符串结尾java 正则包含指定字符串_正则检验以固定字符串结尾java_03

 

如果你有更好的解决方案或者发现文中有不足之处,欢迎留言评论。^_^

2021.07.09 

Russell