Python:检查单词列表中的任何单词是否与正则表达式模式列表中的任何模式匹配

Python:检查单词列表中的任何单词是否与正则表达式模式列表中的任何模式匹配,python,regex,Python,Regex,我有一个很长的单词列表和一个.txt文件,我是这样读的: with open(fileName, "r") as f1: pattern_list = f1.read().split('\n') print pattern_list[:7] # ['abandon*', 'abuse*', 'abusi*', 'aching', 'advers*', 'afraid', 'aggress*'] 为了便于说明,前七个选项如下所示: with open(fileName, "r") a

我有一个很长的单词列表和一个.txt文件,我是这样读的:

with open(fileName, "r") as f1:
    pattern_list = f1.read().split('\n')
print pattern_list[:7] 
# ['abandon*', 'abuse*', 'abusi*', 'aching', 'advers*', 'afraid', 'aggress*']
为了便于说明,前七个选项如下所示:

with open(fileName, "r") as f1:
    pattern_list = f1.read().split('\n')
print pattern_list[:7] 
# ['abandon*', 'abuse*', 'abusi*', 'aching', 'advers*', 'afraid', 'aggress*']
我想知道何时我将输入字符串中的一个单词匹配到pattern_列表中的任何单词/模式。下面的方法很有效,但我发现了两个问题:

  • 首先,每次检查新的字符串输入时,重新编译模式列表中的每一项似乎效率很低。。。但是,当我试图将re.compile(raw_str)对象存储在一个列表中时(为了能够将已经编译的正则表达式列表重新用于类似于
    的东西,如果在正则表达式编译列表中有w:
    ,它就不能正常工作)
  • 其次,它有时并不像我期望的那样工作——注意它是如何工作的
    • 虐待*与虐待相匹配
    • 虐待*与虐待和虐待相匹配
    • 疼痛与疼痛相匹配
  • 我做错了什么?我怎样才能更有效率?提前感谢您对noob的耐心,并感谢您的洞察力

    string_input = "People who have been abandoned or abused will often be afraid of adversarial, abusive, or aggressive behavior. They are aching to abandon the abuse and aggression."
    for raw_str in pattern_list:
        pat = re.compile(raw_str)
        for w in string_input.split():
            if pat.match(w):
                print "matched:", raw_str, "with:", w
    #matched: abandon* with: abandoned
    #matched: abandon* with: abandon
    #matched: abuse* with: abused
    #matched: abuse* with: abusive,
    #matched: abuse* with: abuse
    #matched: abusi* with: abused
    #matched: abusi* with: abusive,
    #matched: abusi* with: abuse
    #matched: ache* with: aching
    #matched: aching with: aching
    #matched: advers* with: adversarial,
    #matched: afraid with: afraid
    #matched: aggress* with: aggressive
    #matched: aggress* with: aggression.
    

    放弃*
    将匹配
    放弃nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
    ,而不是
    放弃asfdsafdasf
    。你想要

    abandon.*
    

    相反。

    对于匹配的shell样式通配符,您可以(ab)使用模块

    由于
    fnmatch
    主要用于文件名比较,因此测试将区分大小写或不区分大小写,具体取决于您的操作系统。因此,您必须规范化文本和模式(在这里,我使用
    lower()

    制作:

    abandon* match ['abandoned', 'abandon']
    abuse* match ['abused', 'abuse']
    abusi* match ['abusive,']
    aching match ['aching']
    advers* match ['adversarial,']
    afraid match ['afraid']
    aggress* match ['aggressive', 'aggression.']
    

    如果
    *
    都在字符串的末尾,您可能需要执行以下操作:

    for pat in pattern_list:
        for w in words:
            if pat[-1] == '*' and w.startswith(pat[:-1]) or w == pat:
                # Do stuff
    

    如果模式使用正则表达式语法:

    m = re.search(r"\b({})\b".format("|".join(patterns)), input_string)
    if m:
        # found match
    

    如果单词是空格分隔的,请使用
    (?:\s+|^)
    (?:\s+|$)
    而不是
    \b

    注意:正则表达式“滥用*”匹配“abus”,后跟零个或多个“e”字符。正则表达式语法与shell通配符不同。(好像你的意思是:“滥用”。)是的,这些不是正则表达式!(但是,如果它们只包含
    [a-z]
    *
    ,您可以使用一些字符串操作将它们变成正则表达式:
    “放弃*
    将变为
    “^about.*$”
    )我认为这种通配符模式应该使用匹配。根据文本文件的大小,读入单个字符串(而不是单独)可能更有意义然后对整个字符串运行
    pat.findall
    ,并解析生成的数组。@svk:这就解释了。regex vs.shell wildcard dif=很高兴知道,非常感谢。