所以我有一个很长的输入字符串,我从一个正则表达式中提取了几位数据。输入由客户端提供,他们经常忘记重要的部分,这些部分不仅是正则表达式匹配所必需的(它们是),但它们是这个正则表达式构建的数据库的组成部分。
我希望能够在输入中指出 where 匹配开始失败,为什么(向他们展示正则表达式接下来会发生什么)。< / p>
性能是一个问题。正则表达式包含几个字段,因此将其分成几个单独的正则表达式匹配可能会令人望而却步。
以下是真实内容的简化版本:
^(?:(?P<doors>\d) Doors).*(?P<transmission>Automatic|Manual)
一些样本输入(和所需的输出):
"3 Doors blah blah blah Manual" # match!
"Guadeloupe blah blah blah Sneezes" # Reply: Missing doors
"2 Doors blah blah blah Psychic" # Reply: Missing transmission
答案 0 :(得分:2)
您的问题太广泛,无法由Python Regex Engine处理。你需要一个有限的自动机引擎(更具体的NFA),编写你自己的解析器并提供字符串,看看它失败的原因和原因。
或者,您可以使用PyParsing,创建一个语法(您可以在PyParsing Wiki中找到的示例)http://pyparsing.wikispaces.com/file/view/dfmparse.py之类的内容 。如果你是PyParsing的新手,会有一个陡峭的学习曲线,但是一旦你掌握了这个概念,实现你想要的就是散步。
答案 1 :(得分:1)
编写解析器的想法(自我的JavaCC时代以来至少已经过了10年)让我觉得有点恼火,而且我没有比它只是运行一堆编译的REGEX更快出售...但是,我想我已经提出了一个合适的解决方法。
我们首先使用单个正则表达式而如果失败,我们会使用增量式正则表达式。如果失败率低,这根本不是性能问题。
REGEXES = [
(r'(?:(?P<doors>\d) Doors)', 'doors'),
(r'.*(?P<transmission>Automatic|Manual)', 'transmission'),
]
FAILS = [(re.compile('^' + r[0], re.IGNORECASE), r[1]) for r in REGEXES]
MATCHER = re.compile('^' + ''.join([r[0] for r in REGEXES]), re.IGNORECASE)
# ... later ...
m = MATCHER.match(input)
if not m:
working = input
for r in FAILS:
s = r[0].split(input)
if len(s) > 1:
working = s[-1] # we use last group in the split
continue
# we have a problem here!!
# we know the group (the regex and the label we gave it)
# we can show the user what we're trying to match and against what
return blah
# otherwise we can start working with m's groups.