首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在正则表达式中“后视断言必须是固定长度”的技术原因是什么?

在正则表达式中“后视断言必须是固定长度”的技术原因是什么?
EN

Stack Overflow用户
提问于 2010-09-26 10:59:54
回答 5查看 30.7K关注 0票数 60

例如,下面的正则表达式将导致故障报告后视断言不是固定长度

代码语言:javascript
复制
#(?()]+)#S

这样的限制对于先行来说是不存在的。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2010-09-26 17:54:51

前视和后视并不像它们的名字所暗示的那样相似。lookahead表达式的工作方式与它是独立正则表达式时的工作方式完全相同,只是它被锚定在当前匹配位置,并且不会消耗匹配的内容。

Lookbehind是一个完全不同的故事。从当前匹配位置开始,它向后一步遍历文本,一次一个字符,尝试在每个位置匹配其表达式。在不可能匹配的情况下,lookbehind必须一直走到文本的开头(记住,一次一个字符),然后才会放弃。将其与先行表达式进行比较,后者只应用一次。

当然,这是一种严重的过于简单化,并不是所有的口味都是这样工作的,但您明白其中的意思。lookbehinds的应用方式从根本上不同于(而且在很大程度上,多效率低于)应用查找头的方式。只有限制回首必须看多远才是有意义的。

票数 91
EN

Stack Overflow用户

发布于 2010-09-26 11:41:14

首先,并不是所有的正则表达式库(如.NET)都是这样的。

对于PCRE,原因似乎是:

对于每个备选方案,lookbehind断言的实现是将当前位置临时移回固定宽度,然后尝试匹配。

(至少,根据http://www.autoitscript.com/autoit3/pcrepattern.html)。

票数 13
EN

Stack Overflow用户

发布于 2016-10-17 11:24:16

PCRE不支持浮点后视,因为它会导致严重的性能问题。这是因为缺乏从右到左的匹配能力: PCRE只能从固定的左侧开始分支,但不能固定可变长度的左侧查找。

一般来说,如果可能的话,试着把你的后视部分分成固定长度的模式。例如,而不是:

代码语言:javascript
复制
(?<=(src|href)=")etc.

(1)使用以下命令:

代码语言:javascript
复制
(?:(?<=src=")|(?<=href="))etc.

(2)或使用\K:

代码语言:javascript
复制
(src|href)="\Ketc.

请注意\K不是真正的回溯,因为它总是在前一个匹配的末尾开始搜索(没有潜在的后退到前一个匹配)。

(3)在一些复杂的仅限后视的情况下,您可以在反转的字符串中使用“反转的”前视表达式进行搜索。不是太优雅,但它是有效的:

代码语言:javascript
复制
.cte(?="=(ferh|crs))
票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3796436

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档