保留/删除包含连续多行的单词的日志行条目,直到下一个时间戳实例?

问题描述 投票:0回答:1

要使用正则表达式删除日志中的单行,我将使用以下内容:

  1. 如果我想删除不包含 TMTimeZoneManager 一词的行,我使用:

    ^(?!.*TMTimeZoneManager.*).+$

  2. 如果我想删除包含 TMTimeZoneManager 一词的行,我使用:

    ^.*(TMTimeZoneManager).*$

日志示例:

2023-10-05 07:47:38.609480+1000 0x789      Default     0x0                  121    0    timed: [com.apple.timed:data] TZ,init,rules,2
2023-10-05 07:47:38.609589+1000 0x789      Default     0x0                  121    0    timed: [com.apple.timed:text] <TMTimeZoneManager: 0x155f0fa80 {
          Location 0 —,
    MobileLockdown 0 —,
} = (null)>
2023-10-05 07:47:38.609594+1000 0x789      Default     0x0                  121    0    timed: [com.apple.timed:data] TZ,reset,reason,init
2023-10-05 07:47:38.610578+1000 0x789      Info        0x0                  121    0    timed: [com.apple.timed:text] Loading time source: ServerState.bundle
2023-10-05 07:47:38.611413+1000 0x8b5      Default     0x284                126    0    locationd: (Network) [com.apple.network:path] nw_path_evaluator_start [XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX <NULL> generic, attribution: developer]
    path: unsatisfied (No network route)
2023-10-05 07:47:38.611680+1000 0x8b5      Activity    0x286                126    0    locationd: (LocationSupport) CL: #Manufacturing service

预期结果是:

删除所有不包含 TMTimeZoneManager 的行将返回:

2023-10-05 07:47:38.609589+1000 0x789      Default     0x0                  121    0    timed: [com.apple.timed:text] <TMTimeZoneManager: 0x155f0fa80 {
          Location 0 —,
    MobileLockdown 0 —,
} = (null)>

仅删除包含单词 TMTimeZoneManager 的行将返回:

2023-10-05 07:47:38.609480+1000 0x789      Default     0x0                  121    0    timed: [com.apple.timed:data] TZ,init,rules,2
2023-10-05 07:47:38.609594+1000 0x789      Default     0x0                  121    0    timed: [com.apple.timed:data] TZ,reset,reason,init
2023-10-05 07:47:38.610578+1000 0x789      Info        0x0                  121    0    timed: [com.apple.timed:text] Loading time source: ServerState.bundle
2023-10-05 07:47:38.611413+1000 0x8b5      Default     0x284                126    0    locationd: (Network) [com.apple.network:path] nw_path_evaluator_start [XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX <NULL> generic, attribution: developer]
    path: unsatisfied (No network route)
2023-10-05 07:47:38.611680+1000 0x8b5      Activity    0x286                126    0    locationd: (LocationSupport) CL: #Manufacturing service

问题是,这对于只有一行的行来说是可以的,但如果日志条目跨越多行,它显然会保持严格,并且删除第一个正则表达式除第 2 行之外的所有行。在正则表达式 2 中,它将删除第 2 行并保留其他所有内容。

我希望能够保留或删除整个日志条目,即使它使用时间戳作为端点跨越多行,因为日期 2023-10-05 将始终指示下一个日志条目的开始日志条目。

它用于草稿和符石应用程序,所以我仅限于正则表达式。

搜索其他帖子,我已经弄清楚如何删除包含 TMTimeZoneManager 的行,即使它们跨越多行:

^.*TMTimeZoneManager.*(?:\n+(?!\d{4}-\d{2}-\d{2}\s\d{2}\.*).+)*

[我现在的问题]我最接近的只保留包含单词 TMTimeZoneManager 的行是:

^(?!.*TMTimeZoneManager.*).+(?:\n+(?!\d{4}-\d{2}-\d{2}\s\d{2}\.*).+)*

它能够正确突出显示其中没有 TMTimeZoneManager 的所有内容,即使是多行。

它的缺点是在要保留的行上,它只会执行第一行。我花了很多时间查看其他帖子,并尝试了许多不同的方法来重写它并尝试将两者结合起来。

/^.*TMTimeZoneManager.*(?:\n+(?!\d{4}-\d{2}-\d{2}\s\d{2}\.*).+)*$|^(?!.*TMTimeZoneManager.*).+(?:\n+(?!\d{4}-\d{2}-\d{2}\s\d{2}\.*).+)*$

我不明白我应该如何让它也做同样的事情(要删除的线的正确结果)但要保留线。

如何修改或更好地编写正则表达式来实现此目的,以便包含第 3、4 和 5 行?如果您能解释我哪里出错了,我将不胜感激。

更新:我一直坚持并尝试更多选择,我找到了一个带有

\b
的选项并且我让它工作了,但如果这是一个黑客并且有更好的方法,请告诉我。我还注意到我留了几秒钟。

删除不包含特定单词的整个日志行条目(包括跨多行)的最终工作版本是:

^\b(?!.*TMTimeZoneManager.*).+(?:\n+(?!\d{4}-\d{2}-\d{2}\.*|$).+)*\n

regex regex-lookarounds
1个回答
0
投票

(您提到的应用程序是iOS应用程序,这可能意味着它们正在使用Swift的正则表达式引擎。)

这是The Best Regex Trick™ 的一个经典用例。你自己已经做得很好了;您距离结果仅几毫米。

你的这个正则表达式已经完成了大部分工作:

^.*TMTimeZoneManager.*(?:\n+(?!\d{4}-\d{2}-\d{2}\s\d{2}\.*).+)*$
|
^(?!.*TMTimeZoneManager.*).+(?:\n+(?!\d{4}-\d{2}-\d{2}\s\d{2}\.*).+)*$

让我们简化一下:

  1. 第一种选择:

     .*TMTimeZoneManager.*
     (?s:(?!\d{4}-\d{2}-\d{2}\s\d{2}).)+
    
    不需要

    ^
    ,因为
    .*
    将在换行符之后立即匹配,因为
    .
    匹配除换行符之外的任何内容。
    (?s:)
    是一个内联修饰符,它允许
    .
    也匹配此类字符。

  2. 第二种选择

     .+(?:\n|\Z)
    

    由于带有

    TMTimeZoneManager
    的行已经被第一个替代方案消耗掉,我们可以将其松开并用
    .+
    匹配其他行,然后换行符 (
    \n
    ) 或整个文本的结尾 (
     \Z
    )。但是,这不会匹配空行。

最后一步是添加一些捕获组:

(.*TMTimeZoneManager.*(?s:(?!\d{4}-\d{2}-\d{2}\s\d{2}).)+)
|
(.+(?:\n|\Z))

在 regex101.com 上尝试一下(PCRE2,但它也可以与 Swift 的正则表达式引擎一起使用)。

如果一行或一组行包含

TMTimeZoneManager

,它将存储在组1中。否则,它将存储在组2中。这两个组是互斥的,这意味着您可以简单地使用
$1
$2
 删除一个并保留另一个。

(我自己没有任何Apple产品来测试正则表达式,但我99%确信它会起作用。)

© www.soinside.com 2019 - 2024. All rights reserved.