【问题标题】:Trying to repeat the regex breaks the regex尝试重复正则表达式会破坏正则表达式
【发布时间】:2016-08-31 17:39:45
【问题描述】:

我有一个匹配以下行之一的有效正则表达式:

  • 以下列表中的标点符号[.,!?;]
  • 以字符串或空格开头的单词。

这是有问题的正则表达式([.,!?;] *|(?<= |\A)[\-'’:\w]+)

我需要它做的是让它匹配 3 个实例。因此,例如,理想的最终结果应该是这样的。

Sample text: "This is a test. Test"

Output
"This" "is" "a"
"is" "a" "test"
"a" "test" "."
"test" "." "Test"

我尝试简单地将 {3} 添加到末尾,希望匹配 3 次。然而,这导致它根本不匹配任何内容或偶尔出现奇怪的字符。我尝试过的另一种可能性是像([.,!?;] *|(?<= |\A)[\-'’:\w]+)([.,!?;] *|(?<= |\A)[\-'’:\w]+)([.,!?;] *|(?<= |\A)[\-'’:\w]+) 这样重复整个正则表达式 3 次,这看起来很可怕,但我希望它会起作用。这会产生奇怪的效果,但前提是至少有一个匹配项是之前列出的标点符号之一。

我们将不胜感激。

我使用new regex module found here 以便进行重叠搜索。

【问题讨论】:

  • 如果您使用 actual Python 代码实际制作一个简短且自包含的示例,则更容易看出哪里出了问题。
  • 您特别想要哪个正则表达式尝试的示例?围绕它的 python 代码应该没有什么区别,但如果你只需要上下文,我可以把它放进去。

标签: python regex python-3.5


【解决方案1】:

你的方法有什么问题

([.,!?;] *|(?<= |\A)[\-'’:\w]+) 模式匹配单个“单元”(指定集合 [.,!?;] 中的单词或单个标点符号后跟 0+ 个空格。因此,当您将此模式提供给 regex.findall 时,它只可以只返回块列表['This', 'is', 'a', 'test', '. ', 'Test']。

解决方案

您可以使用稍微不同的方法:匹配所有单词,以及所有不是单词的块。这是一个演示(注意C'est 和AUX-USB 被视为单个“单词”):

>>> pat = r"((?:[^\w\s'-]+(?=\s|\b)|\b(?<!')\w+(?:['-]\w+)*))\s*((?1))\s*((?1))"
>>> results = regex.findall(pat, text, overlapped = True)
>>> results
[("C'est", 'un', 'test'), ('un', 'test', '....'), ('test', '....', 'aux-usb')]

这里,模式有 3 个捕获组,第二个和第三个包含与组 1 中相同的模式((?1) 是一个子例程调用,用于避免重复相同的模式用于第 1 组)。第 2 组和第 3 组可以用空格分隔(不一定,否则粘在单词上的标点符号将不匹配)。另外,请注意 (?&lt;!') 的负面回溯,这将确保 C'est 被视为单个实体。

说明

图案详情:

  • ((?:[^\w\s'-]+(?=\s|\b)|\b(?&lt;!')\w+(?:['-]\w+)*)) - 组 1 匹配:
    • (?:[^\w\s'-]+(?=\s|\b) - 除[a-zA-Z0-9_]、空格、' 和 - 之外的 1+ 个字符,紧跟空格或单词边界
    • | - 或
    • \b(?&lt;!')\w+(?:['-]\w+)*) - 1+ 个单词字符不以 ' 开头(由于 (?&lt;!')),以单词边界 (\b) 开头,后面跟 0+ 个 - 或 ' 序列,后面跟 1 + 单词字符。
  • \s* - 0+ 个空格
  • ((?1)) - 第 2 组(与第 1 组相同的模式)
  • \s*((?1)) - 见上文

【讨论】:

  • 这很有趣,我得稍微弄乱一下。它几乎可以按原样工作,但会切断连字符和缩略词,例如“我们是”或“X 射线”。
  • 这正是我所需要的,非常感谢!我很想知道为什么([.,!?;] *|(?&lt;= |\A)[\-'’:\w]+){3} 不起作用。
  • 我现在将添加解释。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-16
相关资源
最近更新 更多