我想在程序的输出日志上进行正则表达式匹配(在Python中)。日志包含一些如下所示的行:
...
VALUE 100 234 568 9233 119
...
VALUE 101 124 9223 4329 1559
...
我想捕获以VALUE开头的第一次出现后出现的数字列表。即,我希望它返回('100','234','568','9233','119')
。问题是我事先并不知道会有多少数字。
我尝试将其用作正则表达式:
VALUE (?:(\d+)\s)+
这匹配线,但它只捕获最后一个值,所以我得到('119')。
答案 0 :(得分:21)
您正在寻找的是解析器,而不是正则表达式匹配。在您的情况下,我会考虑使用一个非常简单的解析器,split()
:
s = "VALUE 100 234 568 9233 119"
a = s.split()
if a[0] == "VALUE":
print [int(x) for x in a[1:]]
您可以使用正则表达式来查看输入行是否符合您的预期格式(使用问题中的正则表达式),然后您可以运行上面的代码而无需检查"VALUE"
并知道{ {1}}转换将始终成功,因为您已经确认以下字符组都是数字。
答案 1 :(得分:11)
>>> import re
>>> reg = re.compile('\d+')
>>> reg.findall('VALUE 100 234 568 9233 119')
['100', '234', '568', '9223', '119']
这不会验证关键字“VALUE”是否出现在字符串的开头,并且它不会验证项目之间只有一个空格,但是如果您可以将其作为单独的步骤(或者如果您根本不需要这样做,然后它会在任何字符串中找到所有数字序列。
答案 2 :(得分:3)
此处未描述的另一个选项是拥有一堆可选的捕获组。
VALUE *(\d+)? *(\d+)? *(\d+)? *(\d+)? *(\d+)? *$
此正则表达式最多可捕获由空格分隔的5个数字组。如果您需要更多潜在的群组,只需复制并粘贴更多*(\d+)?
块。
答案 3 :(得分:2)
你可以运行你的主要匹配正则表达式然后在这些匹配上运行二级正则表达式来获取数字:
matches = Regex.Match(log)
foreach (Match match in matches)
{
submatches = Regex2.Match(match)
}
当然,如果您不想编写完整的解析器,也可以这样做。
答案 4 :(得分:0)
我有同样的问题,我的解决方案是使用两个正则表达式:第一个匹配我感兴趣的整个组,第二个解析子组。例如,在这种情况下,我从这开始:
VALUE((\s\d+)+)
这应该导致三个匹配:[0]整行,[1]值后面的东西[2]最后一个空格+值。
[0]和[2]可以忽略,然后[1]可以用于以下内容:
\s(\d+)
注意:这些regexp没有经过测试,我希望你能得到这个想法。
Greg's answer不能为我工作的原因是因为解析的第二部分更复杂,而不仅仅是一些用空格分隔的数字。
但是,我会诚实地使用Greg的解决方案来解决这个问题(它可能更有效率)。
我正在写这个答案,以防有人正在寻找我需要的更复杂的解决方案。
答案 5 :(得分:-1)
您可以使用re.match
首先进行检查,然后调用re.split
使用正则表达式作为分隔符。
>>> s = "VALUE 100 234 568 9233 119"
>>> sep = r"\s+"
>>> reg = re.compile(r"VALUE(%s\d+)+"%(sep)) # OR r"VALUE(\s+\d+)+"
>>> reg_sep = re.compile(sep)
>>> if reg.match(s): # OR re.match(r"VALUE(\s+\d+)+", s)
... result = reg_sep.split(s)[1:] # OR re.split(r"\s+", s)[1:]
>>> result
['100', '234', '568', '9233', '119']
分隔符"\s+"
可能更复杂。