我有一个字符串,我想替换所有不是x.x
形式的浮点数,但仍然在每个浮点数之间保留一个空格:
my $substitute_this = "ABC123 5.4 6.2 9.7 3.8 7.3";
my $substitution = $substitute_this =~ s/(some regex)/(something else?)/gr;
print $substitution; #5.4 6.2 9.7 3.8 7.3
我真的不知道怎么做到这一点,我知道如何替换浮子:
s/[-+]?[0-9]+\.[0-9]+//gr
我知道要在角色类中取消匹配,我会做类似
的事情[^0-9]
但浮点数的正则表达式是如此之长,我不知道如何否定它。第二个问题是每个浮点之间只有一个空格,我不知道如何完成。
答案 0 :(得分:2)
我认为首先提取所有花车会更容易:
my @floats = $substitute_this =~ /(?<!\S)([+-]?\d+\.\d+)(?!\S)/g;
然后将它们连接成一个字符串:
print join(' ', @floats);
编辑:正如Jiri Klouda在下面指出的那样,这个浮点数的正则表达式相当简单,但它只是一个例子。如果需要,您可以调整它。关键是这种方法让你颠倒了你想要做的事情的逻辑,所以你不必尝试匹配不是浮点数的任何东西(这很难),但你必须匹配 浮动的任何东西。
答案 1 :(得分:0)
作为@redneb解决方案的替代方案,一次性RegEx就是这样的:
\d++\.\d++(?= +|\Z)(*SKIP)(?!)|[^\s]+ *|\s(?=\s)
的Perl:
echo "5.23 ABC123 5.4 6.2965 9.7 3.8 7.3 5.3.3 ABC.2356" | perl -ne "s/\d++\.\d++(?= +|\Z)(*SKIP)(?!)|[^\s]+ *|\s(?=\s)//g; print;"
输出:
5.23 5.4 6.2965 9.7 3.8 7.3
Live demo(使用全局匹配并替换为空)
答案 2 :(得分:0)
此解决方案使用全局正则表达式模式匹配来查找所有浮点数 - 可选符号,数字,点,数字 - 既不在前面也不在后面跟着非空格字符。结果列表只是使用空格连接并返回到原始变量
我无法判断你是否有任何其他格式的数字(例如,没有小数点)但你说“替换所有不是xx形式的浮点数”所以这是我编码的内容,加上你后面提到的可选符号字符
use strict;
use warnings 'all';
use feature 'say';
my $s = "ABC123 5.4 6.2 9.7 3.8 7.3";
$s = join ' ', $s =~ / (?<!\S) [+-]? \d+ \. \d+ (?!\S) /xg;
say $s;
5.4 6.2 9.7 3.8 7.3
答案 3 :(得分:0)
您可以在列表上使用map解决此问题:
sub extract_float {
# split string with null char (\s+)
my @array = split(/\s+/, shift);
# anonymous function who return string only if
# arguments is in form `integer.integer`
my $fun = sub { $_ =~ !\d+\.\d+! };
# map $fun on @array
my @map = map(&$fun, @array);
# convert @array in string (each value separated with space)
join(" ", @map);
}
sub extract_float_oneline {
join(" ", map({$_ =~ /(\d+\.\d+)/} split(/\s+/, shift)));
}
my $string = "ABC123 5.4 6.2 9.7 3.8 7.3";
print extract_float($string)."\n";
# 5.4 6.2 9.7 3.8 7.3
print extract_float_oneline($string)."\n";
# 5.4 6.2 9.7 3.8 7.3