Perl正则表达式可对带引号或不带引号的项目进行分组,并忽略空格

rcdsox

我有一些数据库信息被提取到临时日志中。我需要编写一个正则表达式来解析它,以便可以将其输入到分析程序中。我需要将每个“字段”分组如下:

  • YYYY-MM-DD HH:MM:SS
  • 设施
  • 严重程度
  • 服务器
  • YYYY-MM-DD:HH:MM:SS
  • 时区
  • IP地址
  • 旧版电子邮件地址
  • FirstName(**可能包含也可能不包含用引号引起来的几个单词)
  • 姓氏(**可能包含或不包含用引号引起来的几个单词)
  • 帐号
  • 程式码
  • UID
  • 电子邮件地址
  • 事件类型
  • 来源
  • 类别

我几乎有正则表达式,但是在分组字段时遇到了问题。具体来说,名字和姓氏。理想情况下,我希望将它们捕获到两个字段中(如果存在引号,则将其删除),但是将FirstName和LastName合并为一个也可以。

当前正则表达式的问题是,尽管将FirstName和LastName分组为一个字段(不理想,但可以接受),但是似乎还有一个额外的字段捕获了一个空格。

这是我要到达的正则表达式:

^(\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2})\s+(\S+)\.(\S+)\s+(\S+)\s+(\d{4}-\d{2}-\d{2}:\s\d{2}:\d{2}:\d{2})\s+(.*?)\s+(.*?)\s+(.*?)\s+(?<!")(.*)(?!")\s+(.*)\s+(.*)\s+(.*)\s+(.*)\s+(.*)\s+(.*)\s+(.*)\s+(.*)$

以下是一些示例事件:

2016-01-29 18:19:54 local1.info server.domain.com 2016-01-29: 11:19:54 MST UNKNOWN UNKNOWN FOO "BAR BAZ" UNKNOWN UNKNOWN UNKNOWN [email protected] PROFILE_CHANGE ProfileChangeProcessor A
2016-01-29 18:20:25 local4.info server.domain.com 2016-01-29: 11:20:25 MST UNKNOWN UNKNOWN "F B" BAZ ABC12345 GP SOME_UID [email protected] EVENT_FROM_SOME_PROCESS UNKNOWN UNKNOWN
2016-01-29 18:23:10 local1.info server.domain.com 2016-01-29: 11:23:10 MST UNKNOWN UNKNOWN FOO BAR UNKNOWN UNKNOWN UNKNOWN [email protected] SOME_CHANGE ProfileChangeProcessor AP
2016-01-29 18:26:24 local1.info server.domain.com 2016-01-29: 11:26:24 MST UNKNOWN [email protected] FOO "B'Baz" UNKNOWN UNKNOWN UNKNOWN  SOME_CHANGE ProfileChangeProcessor O
2016-01-29 18:26:55 local1.info server.domain.com 2016-01-29: 11:26:55 MST UNKNOWN [email protected] "FOO OR BAR" BAZ SXR12646 GP UNKNOWN  SOME_CHANGE ProfileChangeProcessor M

这是我通过Perl内联表达式运行它时的输出:

$ cat foo.txt | perl -ne '/^(\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2})\s+(\S+)\.(\S+)\s+(\S+)\s+(\d{4}-\d{2}-\d{2}:\s\d{2}:\d{2}:\d{2})\s+(.*?)\s+(.*?)\s+(.*?)\s+(?<!")(.*)(?!")\s+(.*)\s+(.*)\s+(.*)\s+(.*)\s+(.*)\s+(.*)\s+(.*)\s+(.*)$/ && print "$1|$2|$3|$4|$5|$6|$7|$8|$9|$10|$11|$12|$13|$14|$15|$16|\n"' 

2016-01-29 18:19:54|local1|info|server.domain.com|2016-01-29: 11:19:54|MST|UNKNOWN|UNKNOWN|FOO "BAR BAZ"|UNKNOWN|UNKNOWN|UNKNOWN|[email protected]|PROFILE_CHANGE|ProfileChangeProcessor|A|
2016-01-29 18:20:25|local4|info|server.domain.com|2016-01-29: 11:20:25|MST|UNKNOWN|UNKNOWN|"F B" BAZ|ABC12345|GP|SOME_UID|[email protected]|EVENT_FROM_SOME_PROCESS|UNKNOWN|UNKNOWN|
2016-01-29 18:23:10|local1|info|server.domain.com|2016-01-29: 11:23:10|MST|UNKNOWN|UNKNOWN|FOO BAR|UNKNOWN|UNKNOWN|UNKNOWN|[email protected]|SOME_CHANGE|ProfileChangeProcessor|AP|
2016-01-29 18:26:24|local1|info|server.domain.com|2016-01-29: 11:26:24|MST|UNKNOWN|[email protected]|FOO "B'Baz"|UNKNOWN|UNKNOWN|UNKNOWN||SOME_CHANGE|ProfileChangeProcessor|O|
2016-01-29 18:26:55|local1|info|server.domain.com|2016-01-29: 11:26:55|MST|UNKNOWN|[email protected]|"FOO OR BAR" BAZ|SXR12646|GP|UNKNOWN||SOME_CHANGE|ProfileChangeProcessor|M|

使用上述正则表达式时的当前问题位于最后两个记录中。在分组#13处,有一个空字段。我不确定该如何解决。如果我无法获得带有输出数据的字段,则无法将其正确加载到分析引擎中。总体而言,我正在寻找是否有更好的方法根据我概述的内容对字段进行分组,并确保不存在空格(或类似字符)的分组。

卢卡斯(Lucas Trzesniewski)

这是我要做的:

^\s*
# date
(?<date>\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2})
# facility.severity
\s(?<facility>\S+)\.(?<severity>\S+)
# server
\s(?<server>\S*)
# date
\s(?<otherDate>\d{4}-\d{2}-\d{2}:\s\d{2}:\d{2}:\d{2})
# time zone
\s(?<timeZone>\S*)
# ip address
\s(?<ip>\S*)
# legacy email address
\s(?<legacyEmailAddress>\S*)
# first name
\s(?|"(?<firstName>[^"\n]+)"|(?<firstName>\S*))
# last name
\s(?|"(?<lastName>[^"\n]+)"|(?<lastName>\S*))
# account number
\s(?<account>\S*)
# program code
\s(?<programCode>\S*)
# uid
\s(?<uid>\S*)
# email address
\s(?<emailAddress>\S*)
# event type
\s(?<eventType>\S*)
# source
\s(?<source>\S*)
# category
\s(?<category>\S*)
\s*$

样本数据演示

  • 首先,当您具有这种模式时,必须使用x修饰符,以便可以将空格放入表达式中
  • 那到底$13什么意思 为您的捕获组命名,这样更好。
  • 由于您可以有空字段,因此我假设字段之间只有一个空格分隔符。你真的不能绕过去
  • 添加更具体的规则\S*,这完全由您决定
  • 至于名称,模式是: (?|"(?<name>[^"\n]+)"|(?<name>\S*))
    • (?|...)分支重置组它使您可以在每个替代方案中重复使用相同的捕获组编号或名称
    • "(?<name>[^"\n]+)" 捕获引号
    • (?<name>\S*) 捕获一个不带引号的名称...其中只有一个可以匹配,并且它们将属于同一捕获组。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

正则表达式不带引号

来自分类Dev

使用正则表达式捕获不带引号的双引号内的字符串

来自分类Dev

正则表达式可以匹配任何带引号的字符串或特定的不带引号的字符串

来自分类Dev

正则表达式匹配忽略双引号的带引号的字符串

来自分类Dev

正则表达式使用不带引号的键/值对中的空格分割字符串

来自分类Dev

将不带引号的特定单词与正则表达式匹配

来自分类Dev

Java正则表达式提取带或不带引号的字段

来自分类Dev

正则表达式以匹配变量或字符串的值(带或不带引号)

来自分类Dev

Java正则表达式提取不带引号的键值

来自分类Dev

PHP正则表达式带引号

来自分类Dev

Bash正则表达式带引号

来自分类Dev

正则表达式用_(Sublime)替换带引号的字符串中的空格

来自分类Dev

正则表达式检索带引号的字符串和引号字符

来自分类Dev

正则表达式处理带引号的字符串和双引号英寸

来自分类Dev

Python正则表达式将带引号的字符串与转义的单引号匹配

来自分类Dev

javascript正则表达式选择带引号的字符串,但不转义引号

来自分类Dev

在python中使用正则表达式删除带引号的双引号

来自分类Dev

复杂的正则表达式,用逗号代替带引号的值,然后删除引号

来自分类Dev

标记嵌套表达式,但忽略带空格的带引号的字符串

来自分类Dev

Golang正则表达式替换不包括带引号的字符串

来自分类Dev

正则表达式查找带引号的字符串中的所有大括号

来自分类Dev

正则表达式,带引号,等号和点的属性/值对

来自分类Dev

在R中的正则表达式内部粘贴带引号的变量

来自分类Dev

正则表达式以提取带引号之间的符号的数字

来自分类Dev

正则表达式查找带引号的字母的字符串

来自分类Dev

正则表达式以匹配所有带引号的句子

来自分类Dev

使用正则表达式解析SQL,但不包括带引号的文字

来自分类Dev

正则表达式查找带引号的字符串中的所有大括号

来自分类Dev

无法在ruby中使用正则表达式突出显示带引号的字符串

Related 相关文章

  1. 1

    正则表达式不带引号

  2. 2

    使用正则表达式捕获不带引号的双引号内的字符串

  3. 3

    正则表达式可以匹配任何带引号的字符串或特定的不带引号的字符串

  4. 4

    正则表达式匹配忽略双引号的带引号的字符串

  5. 5

    正则表达式使用不带引号的键/值对中的空格分割字符串

  6. 6

    将不带引号的特定单词与正则表达式匹配

  7. 7

    Java正则表达式提取带或不带引号的字段

  8. 8

    正则表达式以匹配变量或字符串的值(带或不带引号)

  9. 9

    Java正则表达式提取不带引号的键值

  10. 10

    PHP正则表达式带引号

  11. 11

    Bash正则表达式带引号

  12. 12

    正则表达式用_(Sublime)替换带引号的字符串中的空格

  13. 13

    正则表达式检索带引号的字符串和引号字符

  14. 14

    正则表达式处理带引号的字符串和双引号英寸

  15. 15

    Python正则表达式将带引号的字符串与转义的单引号匹配

  16. 16

    javascript正则表达式选择带引号的字符串,但不转义引号

  17. 17

    在python中使用正则表达式删除带引号的双引号

  18. 18

    复杂的正则表达式,用逗号代替带引号的值,然后删除引号

  19. 19

    标记嵌套表达式,但忽略带空格的带引号的字符串

  20. 20

    Golang正则表达式替换不包括带引号的字符串

  21. 21

    正则表达式查找带引号的字符串中的所有大括号

  22. 22

    正则表达式,带引号,等号和点的属性/值对

  23. 23

    在R中的正则表达式内部粘贴带引号的变量

  24. 24

    正则表达式以提取带引号之间的符号的数字

  25. 25

    正则表达式查找带引号的字母的字符串

  26. 26

    正则表达式以匹配所有带引号的句子

  27. 27

    使用正则表达式解析SQL,但不包括带引号的文字

  28. 28

    正则表达式查找带引号的字符串中的所有大括号

  29. 29

    无法在ruby中使用正则表达式突出显示带引号的字符串

热门标签

归档