前 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'

的行