在特定位置匹配

时间:2017-05-03 11:37:49

标签: python regex

这是 this question 的后续行动(虽然我没有问过)。试着回答,我遇到了几个问题。

考虑字符串strings123[abc789<span>123</span>def<span>456</span>000]strings456,如何匹配方括号中未被span中的Python标记包围的数字(使用较新的regex模块)?
在示例字符串中,这将是789000

<小时/> 我正在摆弄\G之类的(demo

(?:\G(?!\A)|\[)
[^\d\]]*
\K
\d+

(*SKIP)(*FAIL)demo):

<span>.*?</span>(*SKIP)(*FAIL)
|
\d+

但无法将两个statements合并:

<span>.*?</span>(*SKIP)(*FAIL)
|
(?:
    (?:\G(?!\A)|\[)
    [^\d\]]*
    (\d+)
    [^\d\]]*
    \K
)

如何做到这一点?

2 个答案:

答案 0 :(得分:3)

我喜欢PyPi regex module的一个原因是它支持无限宽度后瞻

  
      
  • 可变长度的后视
  •   
     

lookbehind可以匹配可变长度的字符串。

>>> import regex
>>> s = 'strings123[abc789<span>123</span>def<span>456</span>000]strings456'
>>> rx = r'(?<=\[[^][]*)(?:<span>[^<]*</span>(*SKIP)(?!)|\d+)(?=[^][]*])'
>>> regex.findall(rx, s)
['789', '000']
>>> 

模式详情

  • (?<=\[[^][]*) - 当前位置左侧必须有[以及除][以外的零个或多个字符
  • (?: - 非捕获组开始
    • <span>[^<]*</span>(*SKIP)(?!) - 匹配<span>,然后匹配<以外的0 +字符(带有[^<]*否定字符类),然后是</span>和在比赛结束位置停止比赛,然后继续寻找下一场比赛
    • | - 或
    • \d+ - 1+位数
  • (?=[^][]*]) - 当前位置右侧的]]以外的零个或多个字符后必须有[

答案 1 :(得分:1)

我想到了一个如下算法。

  1. 在其中搜索方括号和内容,并将结果存储在变量中。正则表达式将是\[[^]]*\]

  2. 现在搜索<span>代码并将其替换为-,只是为了简化下一步。正则表达式为(<span>.*?</span>)

  3. 现在,除了<span>标签之外,您将留下方括号的内容。只需使用\d+进行搜索即可匹配数字。