Python正则表达式测试句子是否有效

Python regex test the sentence is valid

ACTIVE_LIST = ACTOR | ACTIVE_LIST and ACTOR
ACTOR = NOUN | ARTICLE NOUN
ARTICLE = a | the
NOUN = tom | jerry | goofy | mickey | jimmy | dog | cat | mouse

通过应用以上规则,我可以生成

a tom 
tom and a jerry 
the tom and a jerry 
the tom and a jerry and tom and dog

但不是

Tom 
the Tom and me

我可以仅使用 python re 模块来检查句子是否正确。我知道如何通过 [abc] 匹配某些字符,但不知道单词。 其实我正在尝试解决这个 ACM problem。如果有人帮助我部分,我可以做剩下的。 这是我在这个舞台上的第一个问题。任何建议或改进高度赞赏。

使用re.compile

re.compile('tom', re.IGNORECASE)

在接下来的主题中,没有 re.compile,您将有其他方法。 (搜索/匹配)

Case insensitive Python regular expression without re.compile

这可以看作是一个NLP(自然语言处理)问题。有一个名为 NLTK(自然语言工具包)的特殊 python 模块最适合用于解决此任务,比使用正则表达式更容易完成。

1) 首先需要下载NLTK(http://www.nltk.org/install.html)

2) 导入 NLTK:

import nltk

3) 创建一个小语法,一个包含四个规则的上下文无关语法 (https://en.wikipedia.org/wiki/Context-free_grammar)。借助 NLTK 的 CFG 模块,只需一行代码即可轻松实现:

acm_grammar = nltk.CFG.fromstring("""
ACTIVE_LIST -> ACTOR | ACTIVE_LIST 'and' ACTOR
ACTOR -> NOUN | ARTICLE NOUN
ARTICLE -> 'a' | 'the'
NOUN -> 'tom' | 'jerry' | 'goofy' | 'mickey' | 'jimmy' | 'dog' | 'cat' | 'mouse' """)

4) 创建一个将使用 acm_grammar:

的解析器
parser = nltk.ChartParser(acm_grammar)

5) 在一些输入上测试它。输入语句必须是包含 comma-separated 个单词(字符串)的列表形式。 split() 方法可用于此:

input= ["a tom", "tom and a jerry", "the tom and a jerry","the tom and a jerry and tom and dog","Tom", "the Tom and me"]

for sent in input:
    split_sent = sent.split()
    try:
        parser.parse(split_sent)
        print(sent,"-- YES I WILL")
    except ValueError:
        print(sent,"-- NO I WON'T")

在这最后一步中,我们检查解析器是否可以根据 acm_grammar 解析一个句子。如果不能,对解析器的调用将导致 ValueError。 这是此代码的输出:

a tom -- YES I WILL
tom and a jerry -- YES I WILL
the tom and a jerry -- YES I WILL
the tom and a jerry and tom and dog -- YES I WILL
Tom -- NO I WON'T
the Tom and me -- NO I WON'T

想了很多还是自己解决了

ARTICLE = ( 'a', 'the')
NOUN = ('tom' , 'jerry' , 'goofy' , 'mickey' , 'jimmy' , 'dog' , 'cat' , 'mouse')

all_a = NOUN +tuple([' '.join([x,y]) for x in ARTICLE for y in NOUN])


def aseKi(str):
    return str in all_a

st = 'the tom and jerry'
st1 = 'tom and a jerry'

st2 = 'tom and jerry and the mouse'

st = 'tom and goofy and goofy and the goofy and a dog and cat'

val = st.split('and')

nice_val = [x.strip() for x in val]


s = [aseKi(x) for x in nice_val]

if all(s):
    print 'YES I WILL'
else:
    print "NO I WON'T"

是的,您可以将其写成正则表达式模式,因为语法是规则的。正则表达式会很长,但可以以相当 straight-forward 的方式生成;一旦你有了正则表达式,你只需编译它并将它应用于每个输入。

关键是把规则变成重复。例如,

STATEMENT = ACTION | STATEMENT , ACTION

可以变成

ACTION (, ACTION)*

当然,这只是问题的一部分,因为您首先必须将 ACTION 转换为正则表达式才能为 STATEMENT.[=18 创建正则表达式=]

问题描述掩盖了一个重要问题,即输入不只是由 lower-case 字母字符和逗号组成。它还包含空格,正则表达式需要在适当的位置坚持空格。例如,上面的 , 可能必须(当然可能)后跟一个(或多个)空格。如果它前面也有一个或多个空格可能没问题;问题描述不清楚

所以 NOUN 的校正正则表达式实际上会变成:

((a|the) +)?(tom|jerry|goofy|mickey|jimmy|dog|cat|mouse)

(我还发现有趣的是所呈现的语法让 VERB 匹配 "hatesssssssss"。我不知道那是否是故意的。)