【问题标题】:Python regex test the sentence is validPython正则表达式测试句子是否有效
【发布时间】:2015-12-31 08:19:03
【问题描述】:
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。如果有人帮助我部分,我可以做剩下的。 这是我在这个舞台上的第一个问题。任何建议或改进都非常感谢。

【问题讨论】:

标签: python regex compiler-construction


【解决方案1】:

使用重新编译

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

在以下主题中,您将有其他方法可以不用重新编译。 (搜索/匹配)

Case insensitive Python regular expression without re.compile

【讨论】:

    【解决方案2】:

    是的,您可以将其写为正则表达式模式,因为语法是常规的。正则表达式会很长,但可以以相当直接的方式生成;获得正则表达式后,您只需编译它并将其应用于每个输入。

    关键是将常规规则变为重复。例如,

    STATEMENT = ACTION | STATEMENT , ACTION
    

    可以变成

    ACTION (, ACTION)*
    

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

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

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

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

    (我还发现有趣的是,所提供的语法让VERB 匹配“hatesssssssss”。我不知道这是否是故意的。)

    【讨论】:

      【解决方案3】:

      这可以看作是一个 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) 在一些输入上测试它。输入的句子必须是用逗号分隔的单词(字符串)的列表形式。 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
      

      【讨论】:

      • 我赞成您的回答,因为这比过去更好。 tnx 阅读链接。最佳答案将被接受。
      • 这有点像用大锤打苍蝇。它完成了这项工作,但如果 OP 的(未说明的)愿望是理解解析,那就丢失了。
      【解决方案4】:

      想了很多,自己解决了

      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"
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-04-29
        • 1970-01-01
        • 2013-08-01
        • 1970-01-01
        • 2012-06-02
        • 1970-01-01
        • 1970-01-01
        • 2017-04-14
        相关资源
        最近更新 更多