我正在尝试转换此日志行:
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,[]
我被困在捕获第二组。想法?
答案 0 :(得分:1)
您可以尝试此模式\[([^\]]++)\].+phone\_numbers\D++(\d++).+SmsJob\:(\w++)
说明:
\[([^\]]++)\]
将匹配方括号内的日期,并成组捕获日期,
.+phone\_numbers\D++(\d++)
将匹配任何一个或多个字符,然后依次匹配phone_number
,然后匹配一个或多个非数字,然后它将使用(\d++)
<捕获组内的实际电话号码。 / p>
.+SmsJob\:(\w++)
将首先匹配任何一个或多个字符,然后依次匹配SmsmJob
,然后再匹配:
,然后再在另一个捕获组中捕获作业ID。
答案 1 :(得分:1)
完全依靠格式的细节,包括所有"
和[]
等
perl -wnE'
say "$1, $2, $3"
if /:\[(.*?)\].*?"phone_numbers":\["(.*?)"\].*?SmsJob:(.*?)"/
' file
我使用显式短语(例如"phone_numbers":
)来锚定所需的模式。
请注意到处都有非贪婪模式。由于我们为需要捕获的内容提供了方便的文本“锚”,因此没有理由让贪婪的模式陷入混乱。他们很难从心理上进行追踪,可能很难正确地做,而且通常效率较低。 †
请注意,我在"
之后使用SmsJob
,因为SmsJob:
在objectKey
中排在最后,因此恰好紧随其后的是"
,这很方便划定要匹配的模式。但是,如果不确定"
是否存在,则需要更改.*?
;也许是[0-9a-zA-Z]
(SmsJob
值允许的最小模式),然后是一个以其结尾的文字字符(例如,
或:
等)。
这将从给定样本中正确捕获时间戳,电话号码和SmsJob。
†问题中诚实尝试的第二种模式无法捕获期望的内容,因为贪婪的.+
一直抓住一切字符串中的最后一对[]
,因为\[.*\]
之后的.+
与最后[]
匹配,因此整个模式都匹配。
答案 2 :(得分:1)
您当前的正则表达式是如此贪婪,并且给定的输入字符串肯定不同。您也没有尝试获得三个捕获组。尝试以下方法:
\[([\d: -]+)\][^][]+\["([^][]+)"\].*?SmsJob:(\w+)
Perl:
perl -ne 'print "$1,$2,$3\n" if /\[([\d: -]+)\][^][]+\["([^][]+)"\].*?SmsJob:(\w+)/' filename
正则表达式细目:
\[
从字面上匹配[
(
第一个捕获组的开始
[\d: -]+
匹配指定字符(数字,:
,空格和-
)的组合)
捕获组结束\]
从字面上匹配]
[^][]+
匹配[
和]
\["
从字面上匹配["
(
第二个捕获组的开始
[^][]+
匹配[
和]
)
捕获组结束"\].*?SmsJob:
最多匹配SmsJob:
(\w+)
匹配单词字符序列并存储在第3个捕获组中答案 3 :(得分:0)
对我来说,您的“ 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;
}