前 3 个单独项目的 Perl 多行正则表达式
Perl multiline regex for first 3 individual items
我正在尝试读取 Perl 中的正则表达式格式。有时我看到的格式不是单行,而是 3 行。
对于下面的单行格式,我可以将正则表达式表示为
/^\s*(.*)\s+([a-zA-Z0-9._]+)\s+(\d+)\s+(.*)/
获取行中的前 3 个单独项目
Hi There FirstName.LastName 10 3/23/2011 2:46 PM
下面是我看到的多行格式。我正在尝试使用
/^\s*(.*)\n*\n*|\s+([a-zA-Z0-9._]+)\s+(\d+)\s+(.*)$/m
获取单个项目但似乎不起作用。
Hi There
FirstName-LastName 8 7/17/2015 1:15 PM
Testing - 12323232323 Hello There
有什么建议吗?可以使用多行正则表达式吗?
注意:在同一输出中,我可以看到单行或多行或两者,因此输出可能如下所示
你好 Line1 FirstName.LastName 2011 年 3 月 23 日 2:46 下午
你好 Line2
Line2FirstName-LastName 8 7/17/2015 1:15 PM
Testing - 12323232323 Hello There
你好 Line3 Line3FirstName.LastName 8 3/21/2011 2:46 下午
您肯定可以在多行上应用正则表达式。
我在单词之间使用否定词 \W+
来匹配 space 和单词之间的换行符(实际上 \W
等于 [^a-zA-Z0-9_]
)。
聊天被视为重复 \w+\W+
块。
如果您提供更具体的输入/输出案例,我可以完善示例代码:
#!/usr/bin/env perl
my $input = <<'__END__';
Hi There
FirstName-LastName 8 7/17/2015 1:15 PM
Testing - 12323232323 Hello There
__END__
my ($chat,$username,$chars,$timestamp) = $input =~ m/(?im)^\s*((?:\w+\W+)+)(\w+[-,\.]\w+)\W+(\d+)\W+([0-1]?\d\/[0-3]?\d\/[1-2]\d{3}\s+[0-2]?\d:[0-5]?\d\s?[ap]m)/;
$chat =~ s/\s+$//; #remove trailing spaces
print "chat -> ${chat}\n";
print "username -> ${username}\n";
print "chars -> ${chars}\n";
print "timestamp -> ${timestamp}\n";
传奇
m/^.../
从行首开始匹配正则表达式(不是替换类型)
(?im)
:不区分大小写的搜索和多行(^/$ 也匹配 start/end 行)
\s*
匹配零个或多个白色 space 字符(匹配 space、制表符、换行符或换页符)
((?:\w+\W+)+)
(匹配组 $chat)匹配一个或多个由单个单词 \w+
(字母、数字、'_')后跟非单词 \W+
组成的模式(不是 \w
的所有内容,包括换行符 \n
)。这稍后被过滤以删除尾随的 whitespaces
(\w+[-,\.]\w+)
: (match group $username) 这是我们的弱点。如果用户名不是由两个由破折号 '-'
或逗号 ','
(UPDATE) 或点 '.'
分隔的正则表达式单词组成,则整个正则表达式无法正常工作(我已经从你的问题中提取了两种可能性,没有直接指定)。
(\d+)
:(匹配组$chars)一个或多个数字组成的数字
([0-1]?\d\/[0-3]?\d\/[1-2]\d{3}\s+[0-2]?\d:[0-5]?\d\s[ap]m)
: (match group $timestamp) 这比其他的要长 拆分它:
[0-1]?\d\/[0-3]?\d\/[1-2]\d{3}
匹配由月份(带有可选的前导零)、日期(带有可选的前导零)和从 1000 到 2999 的年份组成的日期(宽松的约束:)
[0-2]?\d:[0-5]?\d\s?[ap]m
匹配时间:hour:minutes,可选space和'pm,PM,am,AM,Am,Pm...'感谢上面不区分大小写的修饰符
可以在线测试here
您的正则表达式表示:
^\s*(.*)\n*\n* # line starts with optional space followed by anything
| # or
\s+([a-zA-Z0-9._]+)\s+(\d+)\s+(.*)$ # spaces followed by any words followed by spaces, digits, spaces, anything at the end of the line
考虑一下:
/^From|To$/
交替贴近序列。
上面真的是说要找到以 'Fro' 开头的行,然后是 'm' 或 'T',然后是 'o',然后是行尾
与此比较:
/^(From|To)$/
上面会找到只有 'From' 或 'To'
的行
我正在尝试读取 Perl 中的正则表达式格式。有时我看到的格式不是单行,而是 3 行。
对于下面的单行格式,我可以将正则表达式表示为
/^\s*(.*)\s+([a-zA-Z0-9._]+)\s+(\d+)\s+(.*)/
获取行中的前 3 个单独项目
Hi There FirstName.LastName 10 3/23/2011 2:46 PM
下面是我看到的多行格式。我正在尝试使用
/^\s*(.*)\n*\n*|\s+([a-zA-Z0-9._]+)\s+(\d+)\s+(.*)$/m
获取单个项目但似乎不起作用。
Hi There
FirstName-LastName 8 7/17/2015 1:15 PM
Testing - 12323232323 Hello There
有什么建议吗?可以使用多行正则表达式吗?
注意:在同一输出中,我可以看到单行或多行或两者,因此输出可能如下所示
你好 Line1 FirstName.LastName 2011 年 3 月 23 日 2:46 下午
你好 Line2
Line2FirstName-LastName 8 7/17/2015 1:15 PM
Testing - 12323232323 Hello There
你好 Line3 Line3FirstName.LastName 8 3/21/2011 2:46 下午
您肯定可以在多行上应用正则表达式。
我在单词之间使用否定词 \W+
来匹配 space 和单词之间的换行符(实际上 \W
等于 [^a-zA-Z0-9_]
)。
聊天被视为重复 \w+\W+
块。
如果您提供更具体的输入/输出案例,我可以完善示例代码:
#!/usr/bin/env perl
my $input = <<'__END__';
Hi There
FirstName-LastName 8 7/17/2015 1:15 PM
Testing - 12323232323 Hello There
__END__
my ($chat,$username,$chars,$timestamp) = $input =~ m/(?im)^\s*((?:\w+\W+)+)(\w+[-,\.]\w+)\W+(\d+)\W+([0-1]?\d\/[0-3]?\d\/[1-2]\d{3}\s+[0-2]?\d:[0-5]?\d\s?[ap]m)/;
$chat =~ s/\s+$//; #remove trailing spaces
print "chat -> ${chat}\n";
print "username -> ${username}\n";
print "chars -> ${chars}\n";
print "timestamp -> ${timestamp}\n";
传奇
m/^.../
从行首开始匹配正则表达式(不是替换类型)(?im)
:不区分大小写的搜索和多行(^/$ 也匹配 start/end 行)\s*
匹配零个或多个白色 space 字符(匹配 space、制表符、换行符或换页符)((?:\w+\W+)+)
(匹配组 $chat)匹配一个或多个由单个单词\w+
(字母、数字、'_')后跟非单词\W+
组成的模式(不是\w
的所有内容,包括换行符\n
)。这稍后被过滤以删除尾随的 whitespaces(\w+[-,\.]\w+)
: (match group $username) 这是我们的弱点。如果用户名不是由两个由破折号'-'
或逗号','
(UPDATE) 或点'.'
分隔的正则表达式单词组成,则整个正则表达式无法正常工作(我已经从你的问题中提取了两种可能性,没有直接指定)。(\d+)
:(匹配组$chars)一个或多个数字组成的数字([0-1]?\d\/[0-3]?\d\/[1-2]\d{3}\s+[0-2]?\d:[0-5]?\d\s[ap]m)
: (match group $timestamp) 这比其他的要长 拆分它:[0-1]?\d\/[0-3]?\d\/[1-2]\d{3}
匹配由月份(带有可选的前导零)、日期(带有可选的前导零)和从 1000 到 2999 的年份组成的日期(宽松的约束:)[0-2]?\d:[0-5]?\d\s?[ap]m
匹配时间:hour:minutes,可选space和'pm,PM,am,AM,Am,Pm...'感谢上面不区分大小写的修饰符
可以在线测试here
您的正则表达式表示:
^\s*(.*)\n*\n* # line starts with optional space followed by anything
| # or
\s+([a-zA-Z0-9._]+)\s+(\d+)\s+(.*)$ # spaces followed by any words followed by spaces, digits, spaces, anything at the end of the line
考虑一下:
/^From|To$/
交替贴近序列。 上面真的是说要找到以 'Fro' 开头的行,然后是 'm' 或 'T',然后是 'o',然后是行尾
与此比较:
/^(From|To)$/
上面会找到只有 'From' 或 'To'
的行