我想编写一个可以在以下字符串中提取2,3或4个字符的正则表达式:
a b
a b c
a b c d
我编写了以下代码来执行此操作:
#!/usr/bin/perl
use strict;
use warnings;
my @a = ("a b", "a b c", "a b c d");
while (defined (my $line = shift @a)) {
my ($c1, $c2, $c3, $c4) = "";
($c1, $c2, $c3) = $line =~ /^(.*?)\s(.*?)\s(.*?)?.*?/;
print "$c1, $c2, $c3\n";
}
但是,上述操作失败,因为在前两个字符串中找不到$c3
。如何使$c3
和$c4
成为可选项,以便正则表达式在没有任何内容匹配时不会失败?
答案 0 :(得分:3)
如何使$ c3和$ c4可选,所以当没有什么可以匹配时,正则表达式不会失败?
除非必须使用个别变量,否则请考虑使用数组来保存所需的字符:
use strict;
use warnings;
my @a = ( "a b", "a b c", "a b c d" );
for my $line (@a) {
my @chars = split ' ', $line;
#my @chars = $line =~ /\S+/g; # Or use this regex to capture the chars
print join( ', ', @chars ), "\n";
}
输出:
a, b
a, b, c
a, b, c, d
希望这有帮助!
答案 1 :(得分:1)
在这种情况下,split比正则表达式更实用,
for my $line (@a) {
my ($c1, $c2, $c3, $c4) = split " ", $line;
print "$c1, $c2, $c3\n";
}
答案 2 :(得分:1)
要考虑字符串中的任意数量的字段,我建议您使用数组而不是标量变量列表。
在任何情况下,如果您有$f1
,$f2
,$f3
,$f4
等变量,则表示您可能需要数组{{1}而是。然后,您可以使用@f
,$f[0]
,$f[1]
,$f[2]
。
喜欢这个
$f[3]
<强>输出强>
use strict;
use warnings;
my @data = ('a b', 'a b c', 'a b c d');
for (@data) {
my @fields = split;
print join(', ', @fields), "\n";
}
答案 3 :(得分:1)
您使用split
获得了一些好的答案。但你也可以用正则表达式轻松完成。你只需要从一个稍微不同的方向攻击它。
#!/usr/bin/perl
use strict;
use warnings;
use 5.010;
my @strings = ("a b", "a b c", "a b c d");
foreach (@strings) {
my @matches = /(\S+)/g;
say "@matches";
}