Python - 仅允许特定单词(变量)和数学运算符作为输入

时间:2016-03-28 18:43:23

标签: python regex validation

python中验证字符串的最佳方法是什么,以便它只包含特定的(预定义的)单词或其他一些字符[例如+, - ,/,*,(,)]?

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

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不是正确的方法......)

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

2 个答案:

答案 0 :(得分:1)

这是规范的lexing和解析问题:如何将一串字符识别为有效令牌并解释它们是否有效?

正则表达式涉及,但不是你想象的方式:当你有一个正式的语法匹配时,正则表达式通常是不够的(你这样做,否则简单地有+没有操作数会被视为有效)。

PLY是一个用Python编写的解析器词法分析器,它本质上是Lex和Yacc的一个端口。解决这个问题需要花费很多的负担,并且需要相当少的代码来完成这个任务。

你的语法几乎就是计算器语法,经过简单的修改(以下是Brackus-Naur格式):

  

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

     

term:term * factor              |期限/因素              |因子

     

因素:IDENTIFIER              | (表达)

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

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

答案 1 :(得分:1)

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

  

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

然后你的正则表达式的轻微调整可以满足它:

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

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

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

除了:你也不需要"吃" \ b边界,因为它们是零宽度,无论如何你都没有消耗任何东西。

DEMO HERE