固定位置和长度字段的正则表达式

Posted

技术标签:

【中文标题】固定位置和长度字段的正则表达式【英文标题】: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 长一个字符。将示例字符串打印为代码而不是块引用应该更清楚地显示这一点。 【参考方案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】:
    正则表达式是这个简单问题的复杂解决方案。 由于输入格式和所需输出的偏移量是固定的,只需逐行读取输入,然后 做一些小的字符串处理。

    如果仍然需要正则表达式,这是一个起点(尽管在您自己的输入数字中,54 和 18 与您想要的答案不匹配,所以我尝试使用 47 和 16,您可以根据需要进行修改) :

    (?

    http://regexr.com?328dm

【讨论】:

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

以上是关于固定位置和长度字段的正则表达式的主要内容,如果未能解决你的问题,请参考以下文章

mysql 正则表达式替换,把指定位置随机数替换成固定数字

如何用固定长度和许多元素编写这个正则表达式

java 正则表达式 如何匹配固定长度的数字

正则表达式中“后向断言必须是固定长度”的技术原因是啥?

非固定长度的正则表达式负回溯

具有至少 1 个数字和 1 个字符且固定长度为 11 的字母数字字符串的正则表达式