【问题标题】:Python Regex either or case [closed]Python正则表达式或大小写[关闭]
【发布时间】:2013-12-25 03:58:34
【问题描述】:

我有一个小模块,可以获取单词的引理及其复数形式。然后它在句子中搜索以查找包含两个单词(单数或复数)的句子。我有它的工作,但我想知道是否有一个更优雅的方式来构建这个表达式。谢谢! 注意:Python2

words = ((cell,), (wolf,wolves))
string1 = "(?:"+"|".join(words[0])+")"
string2 = "(?:"+"|".join(words[1])+")"
pat = ".+".join((string1, string2)) +"|"+ ".+".join((string2, string1))
# Pat output: "(?:cell).+(?:wolf|wolves)|(?:wolf|wolves).+(?:cell)"

然后搜索:

pat = re.compile(pat)
for sentence in sentences:
    if len(pat.findall(sentence)) != 0:
        print sentence+'\n'

【问题讨论】:

  • 性能是个问题吗?还是您只是在寻找代码审查?
  • 这个问题似乎是题外话,因为它要求进行代码审查。应该移到codereview.stackoverflow.com
  • 性能是主要关注点,是的。

标签: python regex nltk lemmatization


【解决方案1】:

类似:

[ x for x in sentences if re.search( '\bcell\b', x ) and
        ( re.search( '\bwolf\b', x ) or re.search( '\bwolves\b', x ) )]

【讨论】:

  • 似乎运行 3 个单独的 re.search() 调用只会损害性能。该模块一次将用于数千个句子,因此速度是一个大问题。
  • @JesseTravis 您正在使用findall,它不会在第一次匹配时停止,而且模式要复杂得多。使用上述版本,如果找不到任何\bcell\b,它将停止,并且不会运行其他两个正则表达式中的任何一个
  • 我会调查的。我认为它也需要 re.search('\bcell', x) 来捕捉复数“细胞”。
  • 我对一个 1m 的文件进行了一些测试,但我的方法仍然比您建议的方法快一些。
【解决方案2】:

问题在于,当您开始添加多个复合环视表达式时,您的算法复杂性就会失控。这将是使用正则表达式解决此问题的一个基本问题。

另一种方法是尝试使用Counter 对每个句子进行一次 O(n) 传递,然后对其进行查询:

#helper function
def count_lemma(counter,*args):
    return sum(counter[word] for word in args)

from collections import Counter
from string import punctuation

for sentence in sentences:
    c = Counter(x.rstrip(punctuation).lower() for x in sentence.split())
    if all(count_lemma(c,*word) for word in words):
        print sentence

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-22
    • 2017-11-13
    • 1970-01-01
    • 2017-01-23
    相关资源
    最近更新 更多