首页 > 解决方案 > 如何重新检查正则表达式中的匹配表达式?

问题描述

我试图在给定文本中捕捉一个基数后面跟着一个点的单词。例如,对于引号中的表达式:

“1.文字

应该返回“ text ”。文本”可以是纯字母或其他数字。

我想出了以下正则表达式,它完全实现了这一点:

r'(?:(?:(?<=\s)|(?<!.))\d+\.\s)([^\s.,:!?]*)'

问题是如果“文本”与非捕获词属于同一类型,则不会再次对其进行检查。例子:

“2. wordX wordY.”:返回“wordX”,预期行为

“3. 4. wordZ.”:返回“4”,这是预期的行为。

我也希望得到“wordZ”,因为它与表达式“4.wordZ.”匹配,但它没有被捕获。

如何在匹配的表达式重叠的地方获得两者?

标签: pythonregex

解决方案


您可以匹配第一个数字点和空格模式,然后开始一个捕获组。

在该捕获组中,您可以选择重复相同的模式,然后是字符类。

然后对于每个匹配在点和空格上拆分。

  • (?<!\S)断言空白边界
  • \d+\.\s匹配数字点和空白字符
  • (捕获组 1
    • (?:\d+\.\s)*匹配数字点和空白字符的可选重复
    • [^\s.,:!?]+匹配字符类中列出的内容的 1 倍以上
  • )关闭组 1

正则表达式演示| Python 演示

import re

pattern = r"(?<!\S)\d+\.\s((?:\d+\.\s)*[^\s.,:!?]+)"
strings = [
    "1. text",
    "2. wordX wordY.",
    "3. 4. wordZ."
]

for s in strings:
    for m in re.finditer(pattern, s):
        print(m.group(1).split(". "))

输出

['text']
['wordX']
['4', 'wordZ']

另一种方法是使用PyPi 正则表达式模块,在后视中使用无限量词来查找左侧的数字点和空格。

这是与上面相同的模式结构,现在只有匹配项在后视中,组值现在是匹配项。

(?<=(?<!\S)\d+\.\s(?:\s\d+\.\s)*)[^\s.,:!?]+

正则表达式演示| Python 演示

import regex

pattern = r"(?<=(?<!\S)\d+\.\s(?:\s\d+\.\s)*)[^\s.,:!?]+"

strings = [
    "1. text",
    "2. wordX wordY.",
    "3. 4. wordZ."
]

for s in strings:
    print(regex.findall(pattern, s))

输出

['text']
['wordX']
['4', 'wordZ']

推荐阅读