使用正则表达式替换替换多个字符

时间:2012-09-11 11:51:24

标签: regex perl

我正在尝试对acpi命令的输出执行正则表达式替换。我的perl one liner是:

acpi | perl -F/,/ -alne 'print $F[1] if ($F[1]=~s!\s|%!!)'

上述一个班轮的输出为87%,而我所需的输出仅为87,因此它不会替换字符串中的%

现在acpi命令的输出是

Battery 0: Discharging, 87%, 05:54:56 remaining

print $F[1]的输出为

ronnie@ronnie:~$  acpi | perl -F/,/ -alne 'print $F[1]'
 87%   #space followed by 87%#
ronnie@ronnie:~$ 

现在奇怪的是,如果我尝试使用相同的perl单线程:

echo " 86%" | perl -nle 'print if s!\s|%!!g'

工作正常并输出86

那么,为什么它不能使用acpi命令。

PS:我知道这可以通过使用sed / awk实现,但我感兴趣的是为什么我的解决方案无效。

5 个答案:

答案 0 :(得分:7)

你的单行无法按预期工作,因为

s!\s|%!!

替换 空白百分号,而不是两者。

如果您想要替换它们,请添加全局/g修饰符:

s!\s|%!!g

正如你在其他例子中巧合的那样。

您也可以考虑使用字符类而不是交流发电机:

s![\s%]!!g

如果您的输出符合您显示的格式,那么最好使用简单的正则表达式:

echo Battery 0: Discharging, 87%, 05:54:56 remaining|perl -nlwe 'print /(\d+)%/'
87

答案 1 :(得分:2)

这个按预期工作:

echo " 86%" | perl -F/,/ -alne 'print $F[1] if ($F[1]=~s!\s*(\d+)%!$1!)'

答案 2 :(得分:2)

您错过了g修饰符

acpi | perl -F/,/ -alne 'print $F[1] if ($F[1]=~s!\s|%!!g)'
                                                    ____^

答案 3 :(得分:2)

您的s!...!...!首先匹配该空间,然后不执行任何其他操作。尝试添加g中的... s!\s|%!!g修饰符。

答案 4 :(得分:2)

我试过这个并且效果很好。

echo "Battery 0: Discharging, 87%, 05:54:56 remaining" | perl -F, -alne '$F[1]=~s/\s|%//g;print $F[1]'
87

问题在于g修饰符。

g实际上是要替换行中的所有匹配项,但默认行为是仅替换第一次出现。 因此,由于$F[1]开头有空格,所以只替换空格,忽略行中其余字符。