Regex 从一批正则表达式中获取第一个成功匹配
我试图从一个字符串中提取一组数据,该字符串可以匹配三种模式中的一种。我有一个已编译正则表达式的列表。我想(按顺序)浏览一遍,然后进行第一场比赛Regex 从一批正则表达式中获取第一个成功匹配,regex,python,Regex,Python,我试图从一个字符串中提取一组数据,该字符串可以匹配三种模式中的一种。我有一个已编译正则表达式的列表。我想(按顺序)浏览一遍,然后进行第一场比赛 regexes = [ compiled_regex_1, compiled_regex_2, compiled_regex_3, ] m = None for reg in regexes: m = reg.match(name) if m: break if not m: print 'ARGL N
regexes = [
compiled_regex_1,
compiled_regex_2,
compiled_regex_3,
]
m = None
for reg in regexes:
m = reg.match(name)
if m: break
if not m:
print 'ARGL NOTHING MATCHES THIS!!!'
这应该是可行的(还没有测试),但它是相当fugly。有没有更好的方法使循环在成功时破裂,或者在失败时爆炸
可能有一些特定于re
的东西我不知道,它也允许您测试多个模式。您可以使用for
循环的子句:
for reg in regexes:
m = reg.match(name)
if m: break
else:
print 'ARGL NOTHING MATCHES THIS!!!'
由于本例中有一个有限集,因此可以使用:
如果您只想知道任何正则表达式是否匹配,则可以使用内置的
any
函数:
if any(reg.match(name) for reg in regexes):
....
但是,这不会告诉您哪个正则表达式匹配
或者,您可以使用|
将多个模式组合成一个正则表达式:
regex = re.compile(r"(regex1)|(regex2)|...")
同样,这不会告诉您哪个正则表达式匹配,但您将有一个match对象,可以用于进一步的信息。例如,您可以找出哪些正则表达式从非无的组中成功:
>>> match = re.match("(a)|(b)|(c)|(d)", "c")
>>> match.groups()
(None, None, 'c', None)
然而,如果任何子正则表达式中也有组,这可能会变得复杂,因为编号将被更改
这可能比单独匹配每个正则表达式要快,因为正则表达式引擎有更大的范围来优化正则表达式。我使用了Dave Kirby建议的方法,但将命名组添加到正则表达式中,以便知道哪一个匹配
regexps = {
'first': r'...',
'second': r'...',
}
compiled = re.compile('|'.join('(?P<%s>%s)' % item for item in regexps.iteritems()))
match = compiled.match(my_string)
print match.lastgroup
regexps={
“第一”:r“…”,
“第二个”:r“…”,
}
compiled=re.compile(“|”).join(“(?P%s)”%item for regexps.iteritems()中的项)
match=compiled.match(我的字符串)
打印match.lastgroup
埃里克在拍摄OP目标的更大画面方面做得更好,不过我会用if-else。我还认为在或表达式中使用print函数没有什么问题+1为纠正OP的Nathon使用适当的else语句
那么我的选择是:
# alternative to any builtin that returns useful result,
# the first considered True value
def first(seq):
for item in seq:
if item: return item
regexes = [
compiled_regex_1,
compiled_regex_2,
compiled_regex_3,
]
m = first(reg.match(name) for reg in regexes)
print(m if m else 'ARGL NOTHING MATCHES THIS!!!')
在Python 2.6或更高版本中:
import itertools as it
m = next(it.ifilter(None, (r.match(name) for r in regexes)), None)
ifilter
调用可以在genexp中进行,但只是有点笨拙,即使用genexp中名称绑定的常用技巧(也称为“幻影嵌套for
子句惯用法”):
但在适用的情况下,itertools
通常更可取
需要2.6
的位是内置的next
,当迭代器耗尽时,它允许您指定默认值。如果必须在2.5或更早版本中进行模拟
def next(itr, deft):
try: return itr.next()
except StopIteration: return deft
+1表示正确,但我得到的印象是,for-else构造被认为是令人困惑的,尽管在许多情况下它正是您想要的,但它似乎不受欢迎(但我希望被驳斥)。我不知道那个。虽然我的眼睛总是把else
和try
联系在一起;除了
语句之外,try
…。我发现了关于
for..的else
至少三次了。。。我总是忘记它。它只是不好的命名,但它确实工作得很好。谢谢,嗯。在我的真实代码中,在打印我的“ARGL…”消息后,我向更高的for
循环抛出continue
。如果python想要清晰的代码,他们就不能用for..else
。请注意,正则表达式的尝试顺序将是未定义的,这可能会产生意外的结果。对,因为我使用了dict。如果改为使用元组列表,或者对该列表中的regexps.items进行排序,那么它就是定义良好的。
m = next((m for r in regexes for m in (r.match(name),) if m), None)
def next(itr, deft):
try: return itr.next()
except StopIteration: return deft