假设我有以下字符串
my $val = "3.4 -22.352 4.0"
目标是自己提取每个十进制数字。每侧或其间可以有任意数量的空间。确保正好有3个数字,而且没有其他垃圾也很重要。我有这样的东西,但它不起作用:
my @parts = ($val =~ /((\s*[-+]?\d{1,3}\.\d{1,3}\s*)){3}/)
if (scalar(@parts) == 3) {
print "Validated!\n";
for my $i (@parts) {
print "$i\n";
}
}
由于某种原因,我得到了最后一次。
答案 0 :(得分:1)
使用split
和looks_like_number
:
use warnings;
use strict;
use Scalar::Util qw(looks_like_number);
my $val = "3.4 -22.352 4.0";
my @parts = split /\s+/, $val;
if (scalar(@parts) == 3) {
my $ok = 0;
for (@parts) {
$ok++ if looks_like_number($_);
}
if ($ok == 3) {
print "Validated!\n";
for my $i (@parts) {
print "$i\n";
}
}
}
答案 1 :(得分:1)
每个捕获组只获得一个值,即使您在其上应用量词也是如此。如果您想要3个值,则必须重复捕获组3次。例如:
my $num = qr/[-+]?\d{1,3}\.\d{1,3}/;
my @nums = $val =~ /^\s*($num)\s+($num)\s+($num)\s*$/;
if(@nums){
print "Valid, and no need to check the number of elements.\n";
}
答案 2 :(得分:1)
您有两组parens,因此返回两个值。两个集都围绕正则表达式的相同部分,因此两个值都是相同的。
验证和提取不一定可能同时进行。
分两步完成,先提取,非常简单:
my @nums = split ' ', $val;
die "Invalid\n" if @parts != 3;
for (@nums) {
die "Invalid\n" if !/^[-+]?[0-9]{1,3}\.[0-9]{1,3}\z/;
}
您可以一步完成,但需要一些冗余:
my $num_pat = qr/[-+]?[0-9]{1,3}\.[0-9]{1,3}/;
my @nums = $val =~ /^($num_pat)\s+($num_pat)\s+($num_pat)\z/
or die "Invalid\n";
答案 3 :(得分:1)
这里有几个问题:
1)如果你想要三个且只有三个数字,你应该在正则表达式中锚定行的开头(^)和结束($)。
2)为什么有两套括号?如上所述,第二对是多余的。
3)当你有一个正则表达式时,返回的值的数量通常由左括号计算(除非你使用?:或其他一些修饰符)。在此示例中,您有两个,因此它只返回两个值。由于冗余括号,每次都会得到两次相同的值。
答案 4 :(得分:1)
my $val = "3.4 -22.352 4.0";
my $length = $val =~ s/((^|\s)\S)/$1/g;
#determines the number of tokens
if ($length == 3)
{
while($val=~/([-+]?[0-9]{1,3}\.[0-9]{1,3})/g)
{
print "$1\n";
}
}
/g
允许您遍历字符串并提取符合您的限制的值(一次一个)。它将执行此操作,直到所有与您的模式匹配的“标记”被迭代完毕。我喜欢这个解决方案,因为它简洁,不需要您创建辅助数组。在一个正则表达式中使用三个提取也是一个更普遍的答案。
答案 5 :(得分:0)
这将需要3个以空格分隔的数字块,每个数字将被分别插入其各自的组中。
(?:(?:^)([-]?[0-9]*?[.]?[0-9]*?)(?=\s))(?:(?:\s)([-]?[0-9]*?[.]?[0-9]*?)(?=\s))(?:(?:\s)([-]?[0-9]*?[.]?[0-9]*?)(?=$))
PHP Code Example:
<?php
$sourcestring="3.4 -22.352 4.0";
preg_match_all('/(?:(?:^)([-]?[0-9]*?[.]?[0-9]*?)(?=\s))(?:(?:\s)([-]?[0-9]*?[.]?[0-9]*?)(?=\s))(?:(?:\s)([-]?[0-9]*?[.]?[0-9]*?)(?=$))/i',$sourcestring,$matches);
echo "<pre>".print_r($matches,true);
?>
$matches Array:
(
[0] => Array
(
[0] => 3.4 -22.352 4.0
)
[1] => Array
(
[0] => 3.4
)
[2] => Array
(
[0] => -22.352
)
[3] => Array
(
[0] => 4.0
)
)