R:(*SKIP)(*FAIL)用于多种模式

das*_*asf 4 regex boolean r

鉴于test <- c('met','meet','eel','elm'),我需要一行代码匹配任何不在'我'或'ee'的e.我写道(ee|me)(*SKIP)(*F)|e,它确实排除了"遇见"和"鳗鱼",但没有"遇见".这是因为|是独家还是?无论如何,有没有一个解决方案只能返回'榆树'?

为了记录,我知道我也可以做(?<![me])e(?!e),但我想知道解决方案是什么(*SKIP)(*F)以及为什么我的线路是错误的.

nha*_*tdh 5

这是正确的解决方案(*SKIP)(*F):

(?:me+|ee+)(*SKIP)(*FAIL)|e
Run Code Online (Sandbox Code Playgroud)

使用以下测试用例在regex101上演示:

met
meet
eel
elm
degree
zookeeper
meee
Run Code Online (Sandbox Code Playgroud)

只有ein elm,first ein degree和last ein zookeeper匹配.

因为ein ee是禁止的,所以禁止任何ein,m并禁止任何e连续的子串e.这解释了子模式(?:me+|ee+).

虽然我知道这种方法不可扩展,但它至少在逻辑上是正确的.

分析其他解决方案

解决方案0

(ee|me)(*SKIP)(*F)|e
Run Code Online (Sandbox Code Playgroud)

我们meet以一个例子为例:

meet        # (ee|me)(*SKIP)(*F)|e
^           # ^

meet        # (ee|me)(*SKIP)(*F)|e
  ^         #        ^

meet        # (ee|me)(*SKIP)(*F)|e
  ^         #               ^
            # Forbid backtracking to pattern to the left
            # Set index of bump along advance to current position

meet        # (ee|me)(*SKIP)(*F)|e
  ^         #                  ^
            # Pattern failed. No choice left. Bump along.
            # Note that backtracking to before (*SKIP) is forbidden,
            # so e in second branch is not tried

meet        # (ee|me)(*SKIP)(*F)|e
  ^         # ^
            # Can't match ee or me. Try the other branch

meet        # (ee|me)(*SKIP)(*F)|e
   ^        #                    ^
            # Found a match `e`
Run Code Online (Sandbox Code Playgroud)

问题是由于me消耗了第一个e,因此ee无法匹配,第二个e可用于匹配.

解决方案1

\w*(ee|me)\w*(*SKIP)(*FAIL)|e
Run Code Online (Sandbox Code Playgroud)

这将只是用ee和跳过所有单词me,这意味着它将无法匹配degree和中的任何内容zookeeper.

演示

解决方案2

(?:ee|mee?)(*SKIP)(?!)|e
Run Code Online (Sandbox Code Playgroud)

与解决方案0类似的问题.当e连续3 个时,前2个e匹配mee?,留下第3个e可用于匹配.

解决方案3

(?:^.*[me]e)(*SKIP)(*FAIL)|e
Run Code Online (Sandbox Code Playgroud)

这会将输入丢弃到最后一个me或者ee,这意味着任何有效的数据都会e在最后一个之前me或者ee不会匹配,就像e在第一个中一样degree.

演示