我试图删除由空格分隔的字符串中的所有数字/标点符号组合,即
$string = " 13-acetate 9-11 777 >3 ctl-54 2!3 ";
应该成为
$string = " 13-acetate ctl-54 ";
我的尝试如下
$string =~ s/s+[d*[:punct:]>]+s+//g;
但是这给了我
$string = " 13-acetate 777 ctl-54 ";
感谢指教我哪里做错了。
问题是您试图在两次传递中匹配相同的空间。你需要使用遍历
s/(?<!S)[dp{Punct}p{Symbol}]+(?!S)//g;
我使用了负的前后查找,这样您就不需要在输入字符串中添加前导和尾随空格。
正如ikegami指出的,你的问题是你试图匹配空格两次。
快速修复原始正则表达式的另一种方法是为开始边界条件创建一个替代:
use strict;
use warnings;
my $string = " 13-acetate 9-11 777 >3 ctl-54 2!3 ";
$string =~ s/(?:G|s+)[d[:punct:]]+s+/ /g;
print $string;
输出:
13-acetate ctl-54
然而,这种方法有缺陷,因为它不允许剥离字符串开头或结尾的单词。这就是为什么在执行边界条件时,负正向和负向后看是更好的。
如果你想用一种聪明的方式去除单词周围的空格,那么下面的方法就可以了:
$string =~ s{(?:G|(s+))[d[:punct:]]+(?:$|(s+))}{
my @spaces = grep defined, $1, $2;
pop @spaces;
"@spaces"
}eg;
输出:
13-acetate ctl-54