在Python中混淆正则表达式的行为

时间:2012-07-06 23:29:30

标签: python regex string

我正在尝试使用python中的re模块匹配特定模式。 我希望匹配一个完整的句子(更准确地说,我会说它们是由空格和/或标点符号分隔的字母数字字符串序列)

例如

  • “这是一个常规判决。”
  • “这也有效”
  • “这就是这一个”

我尝试了正则表达式的各种组合,但我无法正确掌握模式的工作,每个表达式给我一个不同但又莫名其妙的结果(我承认我是初学者,但仍然)。


我试过了:

  • “((\ W +)(\ S'))*”

    据我所知,这应该匹配一个或多个alpha字母数字,贪婪地跟随一个或没有空格字符,然后它应该贪婪地匹配整个模式。这不是它似乎做的,所以显然我错了,但我想知道为什么。 (我希望这会将整个句子作为结果返回) 我得到的上面提到的第一个样本字符串的结果是[('sentence','sentence',''),('','',''),('','',''),('' ','','')]。

  • “(\ w +?)*”

    我甚至不确定这个应该如何工作。官方文档(python help('re'))表示,+,?匹配前面RE的x或x(贪婪)重复。 在这种情况下,只需将前面的RE空间用于'?'或是'\ w +'前面的RE?什么是“”运算符的RE?我得到的输出是['句子']。

  • 其他如“(\ w + \ s?)+)”; “((\ w *)(\ s ??))等基本上是同一想法的变体,即句子是一组阿尔法数字,后面是单个/有限数量的空格,这个模式重复在结束了。

有人可以告诉我哪里出错了,为什么,为什么上面的表达方式不像我期望的那样工作?


P.S我最终得到“[\ w] +”为我工作,但有了这个我不能限制继续的空白字符数。

4 个答案:

答案 0 :(得分:4)

您对正则表达式的推理是正确的,您的问题来自于使用*的捕获组。这是另一种选择:

>>> s="This is a regular sentence."
>>> import re
>>> re.findall(r'\w+\s?', s)
['This ', 'is ', 'a ', 'regular ', 'sentence']

在这种情况下,您可能更有意义使用\b来匹配单词边界。

>>> re.findall(r'\w+\b', s)
['This', 'is', 'a', 'regular', 'sentence']

或者,您可以通过re.match匹配整个句子并使用re.group(0)来获得整场比赛:

>>> r = r"((\w+)(\s?))*"
>>> s = "This is a regular sentence."
>>> import re
>>> m = re.match(r, s)
>>> m.group(0)
'This is a regular sentence'

答案 1 :(得分:3)

这是一个很棒的正则表达式教程网站:

http://regexone.com/

这是一个与给出的例子匹配的正则表达式:

([a-zA-Z0-9,\. ]+)

答案 2 :(得分:0)

为什么要在延续中限制空格字符数?因为句子可以包含任意数量的单词(字母数字字符序列)和行中的空格,而是句子是以标点符号结尾的文本区域,或者更确切地说是包含空格的上述序列中的某些内容。

([a-zA-Z0-9\s])*

上述正则表达式将匹配一个句子,其中它是一系列或多个系列的空格。您可以将其细化为以下内容:

([a-zA-Z0-9])([a-zA-Z0-9\s])*

其中只是说明上述序列必须以字母数字字符开头。

希望这就是你要找的东西。

答案 3 :(得分:0)

也许这会有所帮助:

import re

source = """
This is a regular sentence.
this is also valid
so is This ONE
how about this one  followed by this one
"""

re_sentence = re.compile(r'[^ \n.].*?(\.|\n|  +)')

def main():
    i = 0
    for s in re_sentence.finditer(source):
        print "%d:%s" % (i, s.group(0))
        i += 1

if __name__ == '__main__':
    main()

我在表达式(\.|\n| +)中使用交替来描述句子结束条件。注意在第三次交替中使用两个空格。第二个空格具有'+'元字符,因此一行中的两个或多个空格将成为句末。