要使用正则表达式删除日志中的单行,我将使用以下内容:
如果我想删除不包含 TMTimeZoneManager 一词的行,我使用:
^(?!.*TMTimeZoneManager.*).+$
如果我想删除包含 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
(您提到的应用程序是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}\.*).+)*$
让我们简化一下:
第一种选择:
.*TMTimeZoneManager.*
(?s:(?!\d{4}-\d{2}-\d{2}\s\d{2}).)+
不需要 ^
,因为 .*
将在换行符之后立即匹配,因为 .
匹配除换行符之外的任何内容。 (?s:)
是一个内联修饰符,它允许 .
也匹配此类字符。
第二种选择
.+(?:\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%确信它会起作用。)