在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))$
请帮忙!
答案 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)$
由于环视是“零宽度断言”,根本不会将当前匹配位置向右移动,所以您可以简单地将它们一个接一个地放置。
答案 2 :(得分:0)
lookbehind必须匹配固定长度的字符串。 regular-expression.info包含以下解释:
坏消息是大多数正则表达式都不允许你在lookbehind中使用任何正则表达式,因为它们不能向后应用正则表达式。正则表达式引擎需要能够在检查lookbehind之前找出要退回的字符数。在评估lookbehind时,正则表达式引擎确定lookbehind内的正则表达式的长度,后退主题字符串中的许多字符,然后从左到右应用正则表达式中的正则表达式,就像使用普通正则表达式一样。 / p>
使用模式bookdown::pdf_document2
,它无法执行此操作,因为它不知道是返回2个字符还是1。
解决方法是分两步执行检查。从正则表达式中取消负面观察。如果你得到一个匹配,做一个额外的检查,看看其中一个模式是否在最后,并从结果集中删除它。