正则表达式匹配多行中最后一次出现的字符串
Regex match last occurrence of a string from multiple lines
我正在尝试匹配日志文件中最后一次出现的字符串。
[03/03/2019 09:16:36] Moving message 123456789 from NEW to PENDING
[03/03/2019 09:16:36] Retrieving file(s) of type DATAWAREHOUSE for 123456
[03/03/2019 09:16:36] collecting warehouse version 7.3.1 files for 123456...
[03/03/2019 09:16:37] Moving message 123456789 from NEW to PENDING
[03/03/2019 09:16:37] Retrieving file(s) of type DATAWAREHOUSE for 123456
[03/03/2019 09:16:37] collecting warehouse version 7.3.1 files for 123456...
[03/03/2019 09:16:38] Moving message 123456789 from NEW to PENDING
[03/03/2019 09:16:39] Retrieving file(s) of type DATAWAREHOUSE for 123456
[03/03/2019 09:16:40] collecting warehouse version 7.3.1 files for 123456...
以上是示例日志文件,其中出现了 3 次以下字符串,
Moving message 123456789 from NEW to PENDING
我需要匹配最后一次出现以获取相应的时间戳“[03/03/2019 09:16:38] ”。
但是当所有这些都在一行中使用贪婪方法 (.*) 时,它工作正常。但是当它们出现在多行中时,它就不起作用了。我还没有尝试过 multiline (m),因为我不确定如何使用它。有人可以帮我构建正则表达式查询来检索最后一次出现的时间戳吗?
示例:https://regex101.com/r/fnwPsB/1
您可以使用
(?s:.*\n)?\K\[(\d{2}\/\d{2}\/\d{4} \d{2}:\d{2}:\d{2})\] Moving message 123456789 from NEW to PENDING
详情
(?s:.*\n)?
- 一个内联修饰符组,它尽可能多地匹配任何 0+ 个字符,直到最后一个 LF 字符,后跟最后一次出现的后续模式。
\K
- 匹配重置运算符从匹配内存缓冲区中移除所有匹配的文本
\[(\d{2}\/\d{2}\/\d{4} \d{2}:\d{2}:\d{2})\] Moving message 123456789 from NEW to PENDING
- 要获取第 1 组中捕获的日期时间的特定行模式。
或者,使用
(?s)(\[\d{2}\/\d{2}\/\d{4} \d{2}:\d{2}:\d{2}\] Moving message 123456789 from NEW to PENDING)(?!.*(?1))
参见 this regex demo。
详情
(?s)
- DOTALL 修饰符使 .
匹配任何字符
(\[(\d{2}\/\d{2}\/\d{4} \d{2}:\d{2}:\d{2})\] Moving message 123456789 from NEW to PENDING)
- 匹配捕获到第 1 组和第 2 组中的日期时间的必要模式
(?!.*(?1))
- 如果在当前位置右侧的任何 0+ 个字符后存在与第 1 组中定义的相同模式,则匹配失败的否定前瞻。
这里是一个不依赖于 PCRE 功能的解决方案,使用负先行:
(?s)\[(\d{2}\/\d{2}\/\d{4} \d{2}:\d{2}:\d{2})\] Moving message 123456789 from NEW to PENDING(?!.* Moving message 123456789 from NEW to PENDING)
日期时间在第一个捕获组中可用。
这里 (?!.* Moving message 123456789 from NEW to PENDING)
是负前瞻,确保我们匹配给定模式的最后一次出现。
我正在尝试匹配日志文件中最后一次出现的字符串。
[03/03/2019 09:16:36] Moving message 123456789 from NEW to PENDING
[03/03/2019 09:16:36] Retrieving file(s) of type DATAWAREHOUSE for 123456
[03/03/2019 09:16:36] collecting warehouse version 7.3.1 files for 123456...
[03/03/2019 09:16:37] Moving message 123456789 from NEW to PENDING
[03/03/2019 09:16:37] Retrieving file(s) of type DATAWAREHOUSE for 123456
[03/03/2019 09:16:37] collecting warehouse version 7.3.1 files for 123456...
[03/03/2019 09:16:38] Moving message 123456789 from NEW to PENDING
[03/03/2019 09:16:39] Retrieving file(s) of type DATAWAREHOUSE for 123456
[03/03/2019 09:16:40] collecting warehouse version 7.3.1 files for 123456...
以上是示例日志文件,其中出现了 3 次以下字符串,
Moving message 123456789 from NEW to PENDING
我需要匹配最后一次出现以获取相应的时间戳“[03/03/2019 09:16:38] ”。 但是当所有这些都在一行中使用贪婪方法 (.*) 时,它工作正常。但是当它们出现在多行中时,它就不起作用了。我还没有尝试过 multiline (m),因为我不确定如何使用它。有人可以帮我构建正则表达式查询来检索最后一次出现的时间戳吗? 示例:https://regex101.com/r/fnwPsB/1
您可以使用
(?s:.*\n)?\K\[(\d{2}\/\d{2}\/\d{4} \d{2}:\d{2}:\d{2})\] Moving message 123456789 from NEW to PENDING
详情
(?s:.*\n)?
- 一个内联修饰符组,它尽可能多地匹配任何 0+ 个字符,直到最后一个 LF 字符,后跟最后一次出现的后续模式。\K
- 匹配重置运算符从匹配内存缓冲区中移除所有匹配的文本\[(\d{2}\/\d{2}\/\d{4} \d{2}:\d{2}:\d{2})\] Moving message 123456789 from NEW to PENDING
- 要获取第 1 组中捕获的日期时间的特定行模式。
或者,使用
(?s)(\[\d{2}\/\d{2}\/\d{4} \d{2}:\d{2}:\d{2}\] Moving message 123456789 from NEW to PENDING)(?!.*(?1))
参见 this regex demo。
详情
(?s)
- DOTALL 修饰符使.
匹配任何字符(\[(\d{2}\/\d{2}\/\d{4} \d{2}:\d{2}:\d{2})\] Moving message 123456789 from NEW to PENDING)
- 匹配捕获到第 1 组和第 2 组中的日期时间的必要模式(?!.*(?1))
- 如果在当前位置右侧的任何 0+ 个字符后存在与第 1 组中定义的相同模式,则匹配失败的否定前瞻。
这里是一个不依赖于 PCRE 功能的解决方案,使用负先行:
(?s)\[(\d{2}\/\d{2}\/\d{4} \d{2}:\d{2}:\d{2})\] Moving message 123456789 from NEW to PENDING(?!.* Moving message 123456789 from NEW to PENDING)
日期时间在第一个捕获组中可用。
这里 (?!.* Moving message 123456789 from NEW to PENDING)
是负前瞻,确保我们匹配给定模式的最后一次出现。