我正在尝试使用一个相当复杂的REGEX表达式(请参阅下面的REGEX101演示(,我从本网站专家创建的表达式中略微修改了该表达式。它解析日志事件的特定模式:
- 1EXE_IN1EXE_CO2CONTENT_ACCESS3CONTENT_ACCESS
这些日志序列将始终以随机选择的EXE_IN
或EXE_CO
事件(序列号之前(开头。这些选择可以是任意数字、任何顺序。在这种情况下,我们只有两个EXE
事件,但这可能是 200。或 1.请注意,有一个序列号,我们需要捕获它。
序列的第二部分将始终是一系列数字前缀CONTENT.ACCESS
事件。长度再次从 1 到无穷大。
下面的演示展示了一个工作示例,并且可能比我更好地传达了这个概念: 演示 1
它可以很好地捕获单独组中的完整匹配项、序列号和事件。
我需要在模式中添加一个时间戳(在序列号之后,前面有一个下划线(,然后解析这个事件日志,例如
2014-08-11- 2014-08-23:03EXE_IN1_11 2014-08-23:03EXE_CO2_12 2014-08-09:17CONTENT_ACCESS3_13 09:17CONTENT_ACCESS
我还需要捕获时间戳。
我试图调整正则表达式,结果好坏参半。请看这个演示:demo2
理想情况下,我希望为每个事件看到这样的东西:
Match n
Full match 266-308 `2_12/08/2014 09:17CONTENT_ACCESS`
Group 1. 266-267 `2`
Group 2. 268-284 `12/08/2014 09:17`
Group 3. 284-308 `CONTENT_ACCESS`
我希望你能帮助我。REGEX101 pcre测试就足够了(作为记录,我在R中使用了与perl兼容的str_match_all_perl函数(。
提前非常感谢。
(d+)_(.*?)(EXE_CO|EXE_IN|CONTENT_ACCESS)
https://regex101.com/r/EHHcKm/1
由于评论,它已更改为(?:G(?!^)(?(?=d+_d{2}/d{2}/d{4}sd{2}:d{2}(?:EXE_CO|EXE_IN))(?<!d_d{2}/d{2}/d{4}sd{2}:d{2}CONTENT_ACCESS))|(?=(?:d+_d{2}/d{2}/d{4}sd{2}:d{2}(?:EXE_CO|EXE_IN))+(?:d+_d{2}/d{2}/d{4}sd{2}:d{2}CONTENT_ACCESS)+))(d+)_(d{2}/d{2}/d{4}sd{2}:d{2})(EXE_CO|EXE_IN|CONTENT_ACCESS)
https://regex101.com/r/EHHcKm/3
Ans 还有另一个版本,它更短(?:G(?!^)(?(?=d+_.{16}(?:EXE_CO|EXE_IN))(?<!d_.{16}CONTENT_ACCESS))|(?=(?:d+_.{16}(?:EXE_CO|EXE_IN))+(?:d+_.{16}CONTENT_ACCESS)+))(d+)_(.{16})(EXE_CO|EXE_IN|CONTENT_ACCESS)
https://regex101.com/r/EHHcKm/4
甚至更短(?:G(?!^)(?(?=d+_.{16}E)(?<!S))|(?=(?:d+_.{16}(?:EXE_CO|EXE_IN))+d+_.{16}C))(d+)_(.{16})(EXE_CO|EXE_IN|CONTENT_ACCESS)
https://regex101.com/r/EHHcKm/5
而且超短(?:G|(?=d+_.{16}E.*CON))(d+)_(.*?)(EXE_CO|EXE_IN|CONTENT_ACCESS)
https://regex101.com/r/EHHcKm/8