"use G in negative variable-length lookbehinds to limit how far back the lookbehind goes"示例



在令人敬畏的正则表达式模块(https://pypi.python.org/pypi/regex(的pypi页面中,指出\G可以"在负可变长度回溯中使用,以限制回溯的距离"。非常有趣,但是该页面没有给出任何示例,当我试图想象一个时,我的白带正则表达式只是窒息。

谁能描述一些示例用例?

下面是一个创造性地使用G和负面回溯的示例:

regex.match(r'bw+b(?:s(w+b)(?<!G.*b1b.*b1b))*', words)

words应该是由单个空格分隔的字母数字字符字符串,例如 "a b c d e a b b c d"

该模式将匹配一系列唯一单词。

  • w+ - 匹配第一个单词。
  • (?:s(w+b) )* - 匹配其他单词...
  • (?<!G.*b1b.*b1b) - ...但是对于添加的每个新单词,请检查它是否尚未出现,直到我们到达G

模式末尾的回溯(限制在 G(可以断言当前匹配的另一个条件,否则这是不可能的。基本上,该模式是在正则表达式中使用 AND 逻辑的前瞻的变体,但不限于整个字符串。

下面是 .Net 中的一个工作示例,它共享相同的功能。
在 Python 2 中使用 findallregex 模块尝试相同的模式会给我一个分段错误,但match似乎有效。

我能想到的一个例子是在正面回望中使用G来用逗号分隔CSV行:

regex.split(r'(?<=G(?:"[^"]*(?:""[^"]*)*"|[^"]*)),', csv)

这是您只能通过可变长度后视和G来执行的变体。

通常,如果要使用split请添加直到行尾的预视,并检查以下记录是否全部有效,如图,(?=([^"]*"[^"]*")*[^"]*$)。这有点烦人,因为您一遍又一遍地匹配字符串上的结尾。

我们也从未明确提到不带引号的值不是逗号([^,](,因为我们使用自上一个逗号以来G来匹配。

这是一个可能比创意更有用的示例。
它使用从上一场比赛(G
(开始的可变长度负回溯向前检查到当前位置。

在这种情况下(?<!Ga+)b,结果是它匹配字符串中所有其他b,其中 b 由一个或多个 a 分隔。

这也可以在固定宽度的后视中完成,例如(?<!Ga)b,结果是它匹配字符串中的所有其他b,其中 b 由一个a分隔。

这是一种模板,其中ab可以是更大的表达式,并且具有更多
内容意义。

(需要注意的一件事是,在负面回溯中使用G时,
很容易满足否定断言。所以,这种事情gotcha写满了!!

没有 Python(最新的,测试版?(来测试它,所以下面使用 C# 控制台应用程序。

string strSrc = "abaabaabaabaabaab";
Regex rxGtest = new Regex(@"(?<!Ga+)b");
Match _m = rxGtest.Match(strSrc);
while (_m.Success)
{
    Console.WriteLine("Found: {0} at position {1}", _m.Groups[0].Value, _m.Index);
    _m = _m.NextMatch();
}

输出:

Found: b at position 4
Found: b at position 10
Found: b at position 16

最新更新