需要在同一行中匹配多个模式 - Perl

时间:2014-11-21 16:21:32

标签: regex perl

我需要在同一行中匹配多个模式。例如,在此文件中:

Hello, Chester [McAllister;Scientist] lives in Boston [Massachusetts;USA;Fenway Park] # McAllister works in USA
I'm now working in New-York [NYC;USA] # I work in USA
...

首先,我希望将每个字符串匹配到括号中,知道可以有多个模式,并且我们可以将1到 n 字符串放入括号中,始终用分号分隔

最后,对于每一行,我需要将值与位于#之后的字符串进行比较。例如,在第一句中,我想比较:

[McAllister;Scientist] & [Massachusetts;USA;Fenway Park] TO "McAllister works in USA"

3 个答案:

答案 0 :(得分:-1)

最整洁的方法可能是使用正则表达式查找由方括号分隔的所有嵌入序列,然后使用mapsplit将这些序列分隔成术语。

该程序演示。

请注意,我假设文件中的所有数据都已读入单个标量变量。你可以改变它来一次处理一行,但是只有当括号内的子序列永远不会分成多行时

use strict;
use warnings;

my $s = <<END_TEXT;
Hello, Chester [McAllister;Scientist] lives in Boston [Massachusetts;USA;Fenway Park] # McAllister works in USA
I'm now working in New-York [NYC;USA] # I work in USA
END_TEXT

my @data = map [ split /;/ ], $s =~ / \[ ( [^\[\]]+ ) \] /xg;

use Data::Dump;
dd \@data;

<强>输出

[
  ["McAllister", "Scientist"],
  ["Massachusetts", "USA", "Fenway Park"],
  ["NYC", "USA"],
]

答案 1 :(得分:-1)

试试这个

这也是你所期望的。

use strict;
use warnings;
open('new',"file.txt");
my @z =map{m/\[[\w;\s]+\]/g} <new>;
print "$_ ,",foreach(@z);

您实际上需要匹配;中由[]分隔的字词。

答案 2 :(得分:-2)

修改 - 鉴于您的更新帖子,这是您可以这样做的方式 它通过代码块构造(?{})在主正则表达式中进行分割 这样做有点棘手,但它避免了做额外的正则表达式。

主正则表达式构造@vals数组并获取目标字符串# target..
在每场比赛中。它严格按行。在每场比赛中构造一个正则表达式 来自@vals并用于匹配目标字符串。

祝你好运!

Perl

use strict;
use warnings;

$/ = undef;
my $data = <DATA>;

my @vals;

while ( $data =~ /
     ^                        # BOL
     (?{ @vals = () })        # Code block - Initialize @vals
     (?:                      # Text & vals cluster
          [^\n\[]*                 # Text - not newline nor '['
          \[                       # '[' opening vals bracket
          (?:                      # Vals cluster
               ( [^\n;\]]* )            # (1), Optional value
               ;?                       # Optional ';'
               (?{
                    # Code block - Push capture onto @vals
                    push (@vals, $^N)
                    if length $^N;
               })
          )*                       # End Vals cluster, do 0 to many times
          \]                       # ']' closing val bracket
     )*                       # End Text & vals cluster, do 0 to many times
     [^\n#]*                  # Text - not newline nor '#'
     \#                       # '#' Target string delimiter
     ( .* )                   # (2), Optional Target string
     $                        # EOL
    /xmg )
{
    my $target = $2;
    print "----------\n$target\n";
    if ( @vals ) {
        my $rx = '(' . join( '|', map { quotemeta } @vals) . ')';
        my $matched = 0;
        while ( $target =~ /$rx/g ) {
           print "$1,"; $matched = 1;
        }
        print "\n" if $matched;
    } 
}

__DATA__

Hello, Chester [McAllister;Scientist] lives in Boston [Massachusetts;USA;Fenway Park] # McAllister works in USA
I'm now working in New-York [NYC;USA] # I work in USA
Nothing [here;;;
Nothing [there;;story;] [;] # End of here story
# More junk here

输出

 McAllister works in USA
McAllister,USA,
----------
 I work in USA
USA,
----------
 End of here story
story,
----------
 More junk here