【问题标题】:Regex for fixed position and length field固定位置和长度字段的正则表达式
【发布时间】:2012-09-24 05:11:03
【问题描述】:

我正在研究一个正则表达式,以从具有固定宽度间距的大型机日志行中提取确切的字符(...正则表达式不是我的强项,顺便说一句)。

我想提取 Status 字段的字段值,该字段是包含以下示例事件中显示的 SUCCESSFUL AUDITLOGON COMPLETEFINAL FAILED AUDIT 值的固定长度字段。

这个固定长度的字段有很多值,所以我不能像我试图做的那样真正提取文字字符串值。

相反,我想提取从事件第 54 位开始且长度为正好 18 个字符的所有字符。

任何关于正则表达式或方法等的帮助或想法,将不胜感激。

528 LOGON   39690  SECURITY LAPTOP    8481 USER AB11 SUCCESSFUL AUDIT  BBB908AFB 06/20/12 09:11:43PM    
528 LOGON   39692  SECURITY LAPTOP    8495 USER AB11 LOGON COMPLETE    BBB908AFB 06/20/12 09:12:12PM    
528 LOGOFF  39699  SECURITY DESKTOP   4476 USER ABEQ FINAL FAILED AUDITAADAFCC01 06/20/12 09:55:49PM   

【问题讨论】:

  • a) 您需要使用特定语言吗?如果是这样,请添加标签并提及它。 b) 是否打算在FINAL FAILED AUDIT 之后没有空格? c) 最后一行的状态字段如何从与前两行相同的位置开始? LOGOFFDESKTOP 分别比 LOGONLAPTOP 长一个字符。将示例字符串打印为代码而不是块引用应该更清楚地显示这一点。

标签: regex


【解决方案1】:

考虑以下通用正则表达式的 powershell 示例。

.{53}(.{18})

示例

    $Matches = @()
    $String = '528 LOGON   39690  SECURITY LAPTOP    8481 USER AB11 SUCCESSFUL AUDIT  BBB908AFB 06/20/12 09:11:43PM    
528 LOGON   39692  SECURITY LAPTOP    8495 USER AB11 LOGON COMPLETE    BBB908AFB 06/20/12 09:12:12PM    
528 LOGOFF  39699  SECURITY DESKTOP   4476 USER ABEQ FINAL FAILED AUDITAADAFCC01 06/20/12 09:55:49PM
528 LOGON   39690  SECURITY LAPTOP    8481 USER AB11 REMEBER TO VOTE   BBB908AFB 06/20/12 09:11:43PM'
    Write-Host start with 
    write-host $String
    Write-Host
    Write-Host found
    ([regex]'.{53}(.{18})').matches($String) | foreach {
        write-host "key at $($_.Groups[1].Index) = '$($_.Groups[1].Value)'"
        } # next match

产量

start with
528 LOGON   39690  SECURITY LAPTOP    8481 USER AB11 SUCCESSFUL AUDIT  BBB908AFB 06/20/12 09:11:43PM    
528 LOGON   39692  SECURITY LAPTOP    8495 USER AB11 LOGON COMPLETE    BBB908AFB 06/20/12 09:12:12PM    
528 LOGOFF  39699  SECURITY DESKTOP   4476 USER ABEQ FINAL FAILED AUDITAADAFCC01 06/20/12 09:55:49PM
528 LOGON   39690  SECURITY LAPTOP    8481 USER AB11 REMEBER TO VOTE   BBB908AFB 06/20/12 09:11:43PM

found
key at 53 = 'SUCCESSFUL AUDIT  '
key at 159 = 'LOGON COMPLETE    '
key at 265 = 'FINAL FAILED AUDIT'
key at 367 = 'REMEBER TO VOTE   '

总结

  • .{53} 跳过前 53 个字符(注意字符串中的第一个位置为零)
  • (.{18}) 查找并返回 18 个字符宽的字段

【讨论】:

    【解决方案2】:
    1. 正则表达式是这个简单问题的复杂解决方案。
    2. 由于输入格式和所需输出的偏移量是固定的,只需逐行读取输入,然后 做一些小的字符串处理。
    3. 如果仍然需要正则表达式,这是一个起点(尽管在您自己的输入数字中,54 和 18 与您想要的答案不匹配,所以我尝试使用 47 和 16,您可以根据需要进行修改) :

      (?

      http://regexr.com?328dm

    【讨论】:

    • 做到了!我弄乱了数字,实际上是 53/18,但看起来它有效。感谢超级快速的帮助!
    • @regexnoob:在这种情况下,最好的感谢信就是接受这个答案(点击旁边的复选标记)。这也将向其他用户显示您的问题已经解决,因此如果将来有人遇到同样的问题,他们知道去哪里找 :) 欢迎使用 StackOverflow!
    • 我仍然很好奇这如何同时捕获示例第 1 行(或第 2 行)和第 3 行。
    • 没关系,通过代码格式,我现在可以看到填充:D.
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多