1

我想在我只有 2 个单词的行上应用正则表达式。我的文件看起来像这样,括号中的单词之间有可变数量的空格:

政客姓名:(何塞·玛丽亚·阿兹纳尔 | 何塞·玛丽亚·阿兹纳尔 | 何塞·玛丽亚·阿兹纳尔 | 何塞·玛丽亚·阿兹纳尔);政客姓名:(托尼·布莱尔 | 托尼·布莱尔 | 托尼·布莱尔 | 托尼·布莱尔);

我想有一个输出:

政客姓名:(托尼·布莱尔 | 托尼·布莱尔 | 托尼·布莱尔 | 托尼·布莱尔 |布莱尔·托尼 | 布莱尔·托尼);

我的代码在每一行上应用正则表达式,我得到如下错误输出:

政客姓名:(何塞·玛丽亚·阿兹纳尔 | 何塞·玛丽亚·阿兹纳尔 | 何塞·玛丽亚·阿兹纳尔 | 何塞·玛丽亚·阿兹纳尔 |玛丽亚·何塞 | 玛丽亚·何塞);

这是我的代码:

use strict;
use warnings;
use Data::Dumper;
use utf8;

open(IN, $ARGV[0]) or die "Can't read file $ARGV[0]\n";
while (my $line=<IN>)
{
    my ($pol,$value) = split(/:/, $line);

    warn Dumper \$pol;
    chomp($value);
    $value=~ s/[  ]+/ /g;
    $value=~ s/\);//g;
    my $n;  
    $n = $1 if ($value =~ /\((.+?)\|/); 
    $n=~ m/(\w*)\s(\w*)/g;
    my $swapname="$2 $1";
    warn Dumper \$swapname;

    print "$pol: $value | $swapname );\n";

}
close(IN); 

我需要做什么来停止处理三字名称?

4

1 回答 1

2
$n=~ m/(\w*)\s(\w*)/g;   # Replace this regex with the one below

使用下面的正则表达式进行比较,$n您还需要将其包含在 中if,否则您的打印将为每个输入执行:-

my $n;  
$n = $1 if ($value =~ /\((.+?)\|/); 
if ($n =~ m/^\s*(\w+)\s(\w+)\s*$/g) {  # Notice `$` to mark the end of 2 words..
    my $swapname="$2 $1";
    warn Dumper \$swapname;

    print "$pol: $value | $swapname );\n";
}

但是,你没有考虑|..之后的下一个值。你需要这样做..它只是考虑第一个值..

所以,你的输出将是: -

Politician_name: (Tony Blair |tony blair | Tony Blair | tony blair | Blair Tony )

2ndtony blair不习惯。您需要为此修改代码。


实际上,您需要一个循环来遍历每个名​​称,以使此代码正常工作。


更新:-我宁愿将您的代码更改为:-

# You should always use lexical variables as file handles..
open my $fh, '<', 'D:\demo.txt' or die $!;

while (<$fh>)  # Don't need use any extra variable here.. Default to $_
{
    my ($pol,$value) = split /:/;  # Do split on $_ by default
    warn Dumper \$pol;

    chomp($value);

    $value=~ s/[  ]+/ /g;
    $value=~ s/\((.*)\);/$1/g;

    my @name = split(/\|/, $value);  # Split your string to an array

    # Filter out array to remove duplicate

    my $_ = $name[0]; 

    if (m/^\s*(\w+)\s(\w+)\s*$/g) {  

        # If first element contains 2 words, proceed with rest of the elements

        print "($value ";  # print the original string you want..

        # Append to it later on the reverse of other array elements

        foreach (@name) {
            if (m/^\s*(\w+)\s(\w+)\s*$/g) {

                my $swapname = "$2 $1";
                warn Dumper \$swapname;

                print "| $swapname ";  # Print swapnames after $value
            }
        }
        print ");\n";  # End the string..
    }
}
close($fh);
于 2012-10-11T10:58:53.877 回答