lookhehind断言长度错误

时间:2018-02-05 17:42:56

标签: regex pcre

在pcre中尝试这个正则表达式行时遇到了一个奇怪的错误:

^(.*[ \-_])?(SS|SSN|SIN|SSIN|SSNSIN|((SOC(IAL)?[_\- ]?SEC(URITY)?|SOC)[_\- 
]?(DISABILITY)?[_\- ]?(INSURANCE)?(NUMBER|NUM|NO|NBR|NR)?))([ \-_].*)?(?<!
(CD|DT|F))$

错误消息是: 你的表达式导致了一个未处理的错误: lookbehind断言不是固定长度 - 偏移量:158

我试图用这个解决它,但它没有工作:

^(.*[ \-_])?(SS|SSN|SIN|SSIN|SSNSIN|((SOC(IAL)?[_\- ]?SEC(URITY)?|SOC)[_\- 
]?(DISABILITY)?[_\- ]?(INSURANCE)?(NUMBER|NUM|NO|NBR|NR)?))([ \-_].*)?(?:(?
<!(CD|DT))|(?<!F))$

请帮忙!

3 个答案:

答案 0 :(得分:6)

对于pcre来说,lookbehind必须具有固定的长度并不完全正确。如果您无法撰写(?<!ab*c)(?<!(AB|BC|C))(?<!(AB|BC|CD))等内容,可以写下以下内容:

(?<!CD|DT|F)

只有当变量的每个分支都有一个固定的长度时,才允许使用可变长度的lookbehind它是一个替换(不包含在一个组中)。

结论,你的lookbehind中的问题是组,而不是每个分支之间不同的字符数。

答案 1 :(得分:2)

一个接一个地放置你的后卫(AND),而不是交替(OR):(?<!F)(?<!CD)(?<!DT),如下:

^(.*[ \-_])?(SS|SSN|SIN|SSIN|SSNSIN|((SOC(IAL)?[_\- ]?SEC(URITY)?|SOC)[_\- ]?(DISABILITY)?[_\- ]?(INSURANCE)?(NUMBER|NUM|NO|NBR|NR)?))([ \-_].*)?(?<!F)(?<!CD)(?<!DT)$

由于环视是“零宽度断言”,根本不会将当前匹配位置向右移动,所以您可以简单地将它们一个接一个地放置。

https://regex101.com/r/m95Jrs/1/

答案 2 :(得分:0)

lookbehind必须匹配固定长度的字符串。 regular-expression.info包含以下解释:

  

坏消息是大多数正则表达式都不允许你在lookbehind中使用任何正则表达式,因为它们不能向后应用正则表达式。正则表达式引擎需要能够在检查lookbehind之前找出要退回的字符数。在评估lookbehind时,正则表达式引擎确定lookbehind内的正则表达式的长度,后退主题字符串中的许多字符,然后从左到右应用正则表达式中的正则表达式,就像使用普通正则表达式一样。 / p>

使用模式bookdown::pdf_document2,它无法执行此操作,因为它不知道是返回2个字符还是1。

解决方法是分两步执行检查。从正则表达式中取消负面观察。如果你得到一个匹配,做一个额外的检查,看看其中一个模式是否在最后,并从结果集中删除它。