1

我有以下代码

my $string = "My mother-in-law lives in Europe";
my @words = split(/(-)|\s+/, $string);

我希望结果像My, mother, -, in, -, law, lives, in, Europe, 但我收到了这个错误

Use of uninitialized value $_ in string,当我尝试使用 foreach 打印数组时。

现在,我正在打印

foreach  (@words)
{
    print "$_" , "\n" if $_;
}

通过修改拆分语句本身是否有更好的解决方案?

4

4 回答 4

3

这是由您提供用于拆分的正则表达式中的捕获组引起的,可以使用Data::Dumper.

perl -MData::Dumper -e 'my $string = "My mother-in-law lives in Europe"; 
  my @words = split(/(-)|\s+/, $string); print Dumper(\@words);'

$VAR1 = [
      'My',
      undef,
      'mother',
      '-',
      'in',
      '-',
      'law',
      undef,
      'lives',
      undef,
      'in',
      undef,
      'Europe'
    ];

您可以使用两种方法:

  1. 用于grep从数组中删除 undef。

    grep defined, split /(-)|\s+/, $string;
    
  2. 使用 split 两次,第一次用于空格,第二次用于连字符。

    map { split /(-)/ } split /\s+/, $string
    
于 2013-09-23T09:14:11.983 回答
3

由于您想在if之后避免该部分print,因此可以使用正则表达式模式,如下面的代码所示:

my $string = "My mother-in-law lives in Europe";
my @words = split(/(?<=-)|(?=-)|\s+/, $string);

foreach  (@words){
    print "$_" , "\n";
}

这将在后面-或前面的空字符串-以及空格上拆分。从而将您-作为单独的元素,并避免捕获组。

输出:

My
mother
-
in
-
law
lives
in
Europe
于 2013-09-23T09:14:24.957 回答
3

这对我有用:

#!/usr/bin/perl
use warnings;
use strict; 

my $string = "My mother-in-law lives in Europe";

my @words = split('(-)|\s+', $string); # Not capturing space

foreach  (@words){
    print "$_" , "\n" if $_;
}

输出:

My
mother
-
in
-
law
lives
in
Europe
于 2013-09-23T09:19:04.267 回答
1

您还可以在拆分之前在连字符之间添加空格,以确保将它们视为单个字段。

#!/usr/bin/perl
use strict;
use warnings;

my @my_line = ("My mother-in-law lives in Europe");

foreach (@my_line) {
    s/-/ - /g;
    print "$_\n" foreach split;
}

输出

My
mother
-
in
-
law
lives
in
Europe

请注意,您也可以使用切片来获取所需的字段。

#!/usr/bin/perl
use strict;
use warnings;

my $string = "My mother-in-law lives in Europe";

print "$_\n" foreach (split /(-)|\s+/, $string)[0, 2 .. 6, 8, 10, 12];
于 2013-09-23T13:17:29.850 回答