我正在尝试使用正则表达式解析以下格式的消息:
/log/<sender>
/error/<sender>
/state/<sender>/<variable_name>
我希望能够检索消息的类型,消息的发送者以及消息是state
消息的变量名称。请注意,日志和错误消息不能在此架构下包含变量名称。
我尝试使用以下模式执行此操作:
address_pattern = re.compile(
r'''/
((?P<type> log)/(?P<sender> [^/]*))
| ((?P<type> error)/(?P<sender> [^/]*))
| ((?P<type> state)/(?P<sender> [^/]*)/(?P<parameter> [^/]*))
''', re.VERBOSE)
但是,这不是一个有效的模式,因为捕获组<type>
和<sender>
被定义了多次(尽管逻辑上只有一个匹配)。
是否有单个正则表达式可以为我解析此字符串并提供三个匹配项?
答案 0 :(得分:2)
怎么样:
r'/(?P<type>log|error|state)/(?P<sender>[^/]+)(?:/(?P<parameter>[^/]+))?'
如果人们尝试/error/<sender>/<variable>
之类的内容,您可以检查语义并抛出错误。
正则表达式有限。根据定义,它们不允许您根据之前的匹配稍后做出决定。一些语法(例如Python的)可以让你作弊并重复使用之前的匹配。例如r'<(a|p|div)></\1>'
,但这就是你可以去的地方。否则,您只能使用DFA。
答案 1 :(得分:0)
我找到的解决方案不是100%正则表达式,但行为相同:
对于字符串s
,您有
state_pat = re.compile(r'/(?P<type>state)/(?P<sender>[^/]+)/(?P<parameter>[^/]+)')
log_pat = re.compile(r'/(?P<type>(log|warning|error))/(?P<sender>[^/]+)')
ping_pat = re.compile(r'/(?P<type>ping)/(?P<sender>[^/]+)')
match = state_pat.match(s) or log_pat.match(s) or ping_pat.match(s)
基本上,将需要重用组名的每个逻辑划分为自己的模式,然后使用or
的短路来返回匹配的第一个。然后,您可以使用match.group('type')
来测试匹配的模式,并且行为与原始问题中的预期一致。
同样,/log/sender/parameter
等字符串也不匹配,您将被退回None
。