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不是正确的方法......)
有人可以告诉我实现目标的最佳方法吗?谢谢。
答案 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边界,因为它们是零宽度,无论如何你都没有消耗任何东西。