条件正则表达式,如何提取匹配的子集?
Posted
技术标签:
【中文标题】条件正则表达式,如何提取匹配的子集?【英文标题】:Conditional Regex, how to extract a subset of a match? 【发布时间】:2013-08-08 17:00:01 【问题描述】:我有系统日志字符串,如下所示:
lwiod[2469]: S-1-5-21-2071757552-4033313730-2397045981-3628|0xC94F000|LOGON|STATUS_SUCCESS|10.10.19.10|10.10.42.40|COMPANY\USERNAME
lwiod[2469]: S-1-5-21-2071757552-4033313730-2397045981-3628|0xC94F000|LOGON|STATUS_SUCCESS|10.10.19.10|10.10.42.40|USERNAME@COMPANY
lwiod[2469]: S-1-5-21-2071757552-4033313730-2397045981-3628|0xC94F000|LOGON|STATUS_SUCCESS|10.10.19.10|10.10.42.40|UNKNOWN
我有一个正则表达式来捕获我需要的所有内容,如下所示:
lwiod\[([0-9]+)\]: (.*)\|(.*)\|LOGON\|STATUS_(.*)\|(.*)\|(.*)\|(COMPANY\\.*|.*\@COMPANY|UNKNOWN)
我还需要该正则表达式做的是仅在字段 7 中给我 USERNAME OR UNKNOWN,我不想要 COMPANY(这是一个 AD 域名),但我遇到了麻烦。
字段 1 为 S-1-5-21-2071757552-4033313730-2397045981-3628,2 为 0xC94F000,...,7 为 USERNAME 或 UNKNOWN。
谢谢!
【问题讨论】:
你使用的是什么正则表达式引擎? 它是基于 SIEM 的 PCRE。我还应该澄清一下,我也需要字段 1 到 6,所以我确实需要这些。我正在尝试做的也是获取字段 7,并且只有用户名或未知,而不必使用编程语言。这些是发送到商业正则表达式解析器的系统日志,除了正则表达式之外我没有其他方法可以调整。 【参考方案1】:好的,我猜你可能会使用这样的东西?
lwiod\[([0-9]+)\]: (.*)\|(.*)\|LOGON\|STATUS_(.*)\|(.*)\|(.*)\|(?:COMPANY\\)?(UNKNOWN|[^@]+)(?:@)?
从您当前的正则表达式来看,COMPANY
似乎是原样,所以我假设相同。否则,我想你可以使用
lwiod\[([0-9]+)\]: (.*)\|(.*)\|LOGON\|STATUS_(.*)\|(.*)\|(.*)\|(?:[^\\]*\\)?(UNKNOWN|[^@]+)(?:@)?
【讨论】:
这在我的测试反向引用中不起作用 7 有USERNAME
然后是 lwiod[2469]: S-1-5-21-2071757552-4033313730-2397045981-3628|0xC94F000|LOGON|STATUS_SUCCESS|10.10.19.10|10.10.42.40|USERNAME
然后是 UNKNOWN
...这是不对的。
好点,但这仅适用于应用于整个字符串块的情况。如果您逐行应用它,它将按预期工作。如果将其应用于整个块,则需要在否定类中添加更多字符,即 \n
以避免换行符。见here。
\n
将跳过最后一行,因为您在最后一行没有换行符...您想使用$
@abc123 不确定您的意思。最后一行对我来说很好......编辑:请参阅我之前评论中的链接。
这是因为您正在使用标志m
,根据您的链接m modifier: multi-line. Causes ^ and $ to match the begin/end of each line (not only begin/end of string)
【参考方案2】:
根据您的语言,只需在管道上拆分并获取最后一个元素。无需为此使用正则表达式!
在 C#.NET 中:
var myString = "lwiod[2469]: S-1-5-21-2071757552-4033313730-2397045981-3628|0xC94F000|LOGON|STATUS_SUCCESS|10.10.19.10|10.10.42.40|COMPANY\USERNAME"
var login = myString.Split('|').Last();
if (login.contains("\"))
login = login.Split('\').Last();
【讨论】:
不幸的是,我没有能力强加任何基于语言的逻辑。这些是发送到商业 SIEM 的系统日志条目,所以我只有一个正则表达式,并且只有一个正则表达式来完成我需要的。我还需要捕获字段 1-6 啊,听起来很悲伤。 :(【参考方案3】:这将为您提供所需的所有字段。要删除公司,您必须添加更复杂的正则表达式,我现在开始编写。
您可以使用组将其捕获到反向引用中:
: ([^|]+)\|([^|]+)\|([^|]+)\|([^|]+)\|([^|]+)\|([^|]+)\|(?:COMPANY\\)?([^|@]+)(?:@COMPANY)?$
这将使您的所有组进入反向引用 1-7。
backreference \7 是您没有公司的用户名。
【讨论】:
我同意你的观点! :)以上是关于条件正则表达式,如何提取匹配的子集?的主要内容,如果未能解决你的问题,请参考以下文章