Perl正则表达式替换所有不是空格的

时间:2016-09-03 20:35:29

标签: regex perl

我有一个字符串,我想替换所有不是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]

但浮点数的正则表达式是如此之长,我不知道如何否定它。第二个问题是每个浮点之间只有一个空格,我不知道如何完成。

4 个答案:

答案 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