编写可识别大小写错误的PCRE正则表达式求助
正则表达式优化方案
问题描述
测试文本:
This is a Sentence which contains
Some capitalization errors.
目前使用的正则:
(?<![.!?]\s)(?<!^)(?<!\sI\s)(?!I['’][a-z])(?!\b(?:Dr|Mr|Mrs)\.[\s\r\n])\b(?!I\b)[A-Z]\w*
这个正则能匹配文本里的Sentence,也能正确避开:
- 单独的
I I'开头的缩写(比如I'm)- Dr.、Mr.、Mrs.这类称谓后的大写单词
但它匹配不到Some,原因是(?<!^)断言排除了行首的单词,而换行后的Some处于新行的开头,被这个断言过滤掉了。
优化后的PCRE正则
下面的正则符合PCRE规范,解决了换行后单词匹配的问题,同时保留所有原有的排除逻辑:
(?<![.!?]\s)(?<!^|\n)(?<!\sI\s)(?!I['’][a-z])(?!\b(?:Dr|Mr|Mrs)\.[\s\r\n])\b(?!I\b)[A-Z]\w*
核心调整
把原正则里的(?<!^)改成(?<!^|\n)——这个修改允许匹配换行后的行首大写单词,同时依然排除整个文档开头的单词(若需匹配文档开头单词,可再调整该断言)。
如果需要拆分两个正则用于文档扫描:
- 匹配行内非句首的目标单词(保留原正则)
- 匹配换行后的目标单词:
(?<=\n)(?<!\n[.!?]\s)(?!I['’][a-z])(?!\b(?:Dr|Mr|Mrs)\.[\s\r\n])\b(?!I\b)(?!\sI\s)[A-Z]\w*
验证结果
调整后的正则可以同时匹配Sentence和Some,不会误匹配需要避开的内容,也没有PCRE的可变宽度断言错误。
内容的提问来源于stack exchange,提问作者Stan Duncan
相关产品推荐
相关产品推荐

