0

我正在尝试使用正则表达式解析以下格式的消息:

  • /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>定义多次(尽管逻辑上只有一个会匹配)。

是否有一个正则表达式可以为我解析这个字符串并提供三个匹配项?

4

2 回答 2

2

关于什么:

r'/(?P<type>log|error|state)/(?P<sender>[^/]+)(?:/(?P<parameter>[^/]+))?'

?

您可以在之后检查语义,如果人们尝试类似/error/<sender>/<variable>.

正则表达式是有限的。根据定义,它们不允许您稍后根据之前的匹配做出决定。某些语法(例如 Python 的)可以让您作弊并重复使用以前的匹配项。例如r'<(a|p|div)></\1>',但这是你能做到的。否则,您只能使用DFA

于 2013-04-23T17:50:16.100 回答
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

于 2013-04-24T11:49:17.450 回答