【问题标题】:Perl capture groups with logs using regular expressionsPerl 使用正则表达式捕获带有日志的组
【发布时间】:2019-03-04 07:23:54
【问题描述】:

我正在尝试转换此日志行:

9:[2019-02-25 00:39:01] production.DEBUG: JOB-VARS : {"phone_numbers":["+9660599291111"],"message":"Your verification code is: 74222","twilio":{},"objectKey":"job:class:App\\Jobs\\SmsJob:000000001328e347000000003113b4f8","connection":"sqs-high","queue":null,"delay":null,"job":{},"JOB-CLASS":"App\\Jobs\\SmsJob"} [] []
16:[2019-02-25 00:50:06] production.DEBUG: JOB-VARS : {"phone_numbers":["+9660533001112"],"message":"Your verification code is: 31231","twilio":{},"objectKey":"job:class:App\\Jobs\\SmsJob:00000000206561fd000000003fb01b05","connection":"sqs-high","queue":null,"delay":null,"job":{},"JOB-CLASS":"App\\Jobs\\SmsJob"} [] []
54:[2019-02-25 03:59:42] production.DEBUG: JOB-VARS : {"phone_numbers":["+9647707771113"],"message":"Your verification code is: 64628","twilio":{},"objectKey":"job:class:App\\Jobs\\SmsJob:0000000003baa9660000000022c0679c","connection":"sqs-high","queue":null,"delay":null,"job":{},"JOB-CLASS":"App\\Jobs\\SmsJob"} [] []

放入如下所示的电子表格:

|       time          |   phone number   |            sms job id          | 
---------------------------------------------------------------------------
| 2019-02-25 00:39:01 | +96605992911111  |000000001328e347000000003113b4f8|
| 2019-02-25 00:50:06 | +96605992911112  |00000000206561fd000000003fb01b05|
| 2019-02-25 03:59:42 | +96605992911113  |0000000003baa9660000000022c0679c|

我试着写这行

perl -ne 'print "$1,$2\n" if /\[(.*?)\].+(\[.*\])/' filename

但我得到的只是这个:

2019-02-25 00:39:01,[]
2019-02-25 00:50:06,[]
2019-02-25 03:59:42,[]

我在捕获第二组时卡住了。想法?

【问题讨论】:

  • 对该文件运行相同的 perl 命令,我得到了一些不同但预期的结果。你确定输入的字符串和你发布的一样吗?
  • @Potato.. 它就像一个魅力!
  • 注意——您正在捕获和打印两件东西,而需要三件?另外,我认为显示的数据是正确的(并且每一行上的数据多一点,如上面给出的链接所示,与该链接中所见的完全相同,不影响模式)
  • 正则表达式中的第二个模式与行尾的 emtpy [] 匹配(在链接中看到,而不是在问题中),因为 .+ 的贪婪
  • 太好了,很高兴听到这一切都很好:) 感谢您的照顾。

标签: regex perl


【解决方案1】:

完全依赖格式的细节,包括"[]

perl -wnE'
    say "$1, $2, $3"  
        if /:\[(.*?)\].*?"phone_numbers":\["(.*?)"\].*?SmsJob:(.*?)"/
' file

我使用明确的短语(如"phone_numbers":)来锚定所需的模式。

注意无处不在的非贪婪模式。由于我们有方便的文本“锚”来捕获我们需要捕获的内容,因此没有理由让贪婪模式失控;他们在精神上更难追踪,可能很难做到正确,而且通常效率较低。

请注意,我在SmsJob 之后使用",因为SmsJob:objectKey 中排在最后,所以它后面恰好有",这对于分隔要匹配的模式很方便。但如果 " 不确定是否存在,则需要更改 .*?;可能是[0-9a-zA-Z]SmsJob 值中允许的最小模式),然后是结束它的文字字符(如,: 等)。

这会从给定的样本中正确捕获时间戳和电话号码以及 SmsJob。


  问题中诚实尝试的第二个模式未能捕捉到预期的结果,因为贪婪的 .+ 一直抓住一切到最后一对字符串中的[],因为.+ 之后的\[.*\] 与最后一个[] 匹配,所以整个模式匹配这种方式。

【讨论】:

    【解决方案2】:

    你可以试试这个模式\[([^\]]++)\].+phone\_numbers\D++(\d++).+SmsJob\:(\w++)

    解释:

    \[([^\]]++)\] 将匹配方括号内的日期,捕获组中的日期,

    .+phone\_numbers\D++(\d++) 将匹配一个或多个任意字符,然后是字面意义上的phone_number,然后是一个或多个非数字,然后它将捕获具有(\d++) 的组内的实际电话号码

    .+SmsJob\:(\w++) 将匹配第一个或多个任意字符,然后是 SmsmJob 字面意思,然后是 :,然后将在另一个捕获组中捕获作业 ID

    【讨论】:

      【解决方案3】:

      你当前的正则表达式太贪心了,给定的输入字符串肯定是不同的。您也没有尝试获得三个捕获组。试试这个:

      \[([\d: -]+)\][^][]+\["([^][]+)"\].*?SmsJob:(\w+)
      

      Perl:

      perl -ne 'print "$1,$2,$3\n" if /\[([\d: -]+)\][^][]+\["([^][]+)"\].*?SmsJob:(\w+)/' filename
      

      正则表达式分解:

      • \[ 匹配 [ 字面意思
      • ( 第一个捕获组的开始
        • [\d: -]+ 匹配指定字符的组合(数字、:、空格和-
      • )捕获组结束
      • \] 匹配 ] 字面意思
      • [^][]+ 匹配除 [] 之外的任何内容
      • \[" 匹配 [" 字面意思
      • ( 第二个捕获组的开始
        • [^][]+ 匹配除 [] 之外的任何内容
      • )捕获组结束
      • "\].*?SmsJob: 匹配到SmsJob:
      • (\w+)匹配单词字符序列并存储在第三个捕获组中

      【讨论】:

        【解决方案4】:

        在我看来,您的“JOB-VARS”非常像 JSON。也许考虑使用 JSON 模块。

        use strict;
        use warnings;
        use JSON;
        my $json= new JSON;
        while (<>) {
            my ($ts, $jtext)= /\[(.*?)\] production.DEBUG: JOB-VARS : (.*)/;
            my ($obj)= $json->decode_prefix($jtext);
            my $phone_number= $obj->{phone_numbers}->[0];
            my $jid= $obj->{objectKey};
            $jid=~ s/^.*://;
            printf "| %19s | %-15s |%32s|\n",$ts,$phone_number,$jid;
        }
        

        【讨论】:

          猜你喜欢
          • 2021-09-06
          • 2022-08-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-08-20
          • 2018-01-15
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多