【问题标题】:Python - only allow specific words (variables) and mathematical operators as inputPython - 仅允许特定单词(变量)和数学运算符作为输入
【发布时间】:2016-03-28 18:43:23
【问题描述】:

在 python 中验证字符串以使其仅包含特定(预定义)单词或其他一些字符的最佳方法是什么 [e.g. +, -, /, *, (, ) ]?

我的最终目标是验证输入(将用作数学公式的字符串),例如:

foo = Valid
fooo = Invalid
bar = Valid
foo/(bar+foo) = Valid
foo*bar - foo = Valid
foo + tree = Invalid
+ = Invalid 

我一直在寻找并找到类似的问题,但没有一个似乎完全符合我的需求。 我设法创建了一个有缺陷的解决方法,我执行以下操作:

allowed_words = ('foo', 'bar', ' + ') # and so on... which is tedious 
input_str = raw_input("foo + bar")
split_string = re.split('(\W+)', input_str)
for word in split_string:
    match = False
    for allowed_word in allowed_words:
        if word == allowed_word:
            match = True
        else:
            pass
    if match == True:
        print "%s is valid" % word
    else:
        print "%s is NOT valid" % word 

我也尝试过使用

if not re.match = ("(\b(?=foo\b|bar\b|\d+\b)\w+\b)|\s|[*/+()-]", input_str)

这似乎在这里工作:http://regexr.com(但我怀疑 re.match 不是正确的方法......)

有人可以告诉我实现目标的最佳方法吗?谢谢。

【问题讨论】:

  • 这听起来很像您想要一种非常简单的特定领域语言而不是纯正则表达式解决方案 - 您需要有一些上下文概念才能做到这一点,这是正则表达式无法提供的你。有很好的Python parsing and lexing 解决方案。你想要一个词法分析器。

标签: python regex validation


【解决方案1】:

这是规范的词法分析和解析问题:如何将字符串识别为有效标记并解释它们是否有效?

涉及正则表达式,但不是你想的那样:当你有一个正式的语法来匹配时,正则表达式本身通常是不够的(你这样做,否则只是有一个没有操作数的 + 会被考虑有效)。

PLY 是一个用 Python 编写的解析器-词法分析器,本质上是 Lex 和 Yacc 的一个端口。它将减轻解决此问题的大部分负担,并且只需要很少的代码即可完成此任务。

您的语法几乎是计算器语法,只需简单修改(以下为 Brackus-Naur 格式):

表达式:表达式+术语 |表达 - 术语 |术语

术语:术语*因子 |术语/因素 |因素

因素:标识符 | (表达式)

这里的IDENTIFIER 可以代表任何你想要的有效词。您甚至可以更进一步,将IDENTIFIER 替换为您希望它解析的特定单词。我链接到的 PLY 页面提供了有关如何实现此功能的完整教程,并附有代码。

对于词法分析器,您只需指定与标记匹配的单个正则表达式。换句话说,您只需要告诉词法分析器将所有看起来像+ 的字符串标记为PLUS,而不是这些字符的所有可能组合。这样就省去了很多麻烦:你不再只有一个正则表达式匹配整个字符串,只有一个正则表达式来识别字符串的每个部分。同样,PLY 文档详尽地涵盖了这一点。

【讨论】:

    【解决方案2】:

    我同意 Liongold 所说的一切。但是让我们暂时假设您的要求只是您明确声明的内容:

    python 中验证字符串的最佳方法是什么 包含特定(预定义的)单词或其他一些字符?

    然后稍微调整一下你的正则表达式就可以满足它:

    ^([\s*\/+()-]*(?=foo\b|bar\b|\d+\b)\w+[\s*\/+()-]*)+$
    

    (我去掉了模式末尾的 |\s|[*/+()-] 并将该逻辑移到括号中,同时还考虑了领先的运算符,然后量化了整个结构:

    运算符/空格 SPECIALWORD 运算符/空格),其中一个或多个,由^$ 锚定,以确保整行必须匹配。

    除此之外:您也不需要“吃掉” \b 边界,因为它们是零宽度的,而且您无论如何都不会消耗任何东西。

    DEMO HERE

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-05
      • 1970-01-01
      相关资源
      最近更新 更多