我编写正则表达式来删除字符串中的多个空格。代码很简单:
my $string = 'A string has more than 1 space';
$string = s/\s+/\s/g;
但是,结果很糟糕:'Asstringshassmoresthans1sspace'。它用“s”字符替换每个空格。
有一个解决方法是代替使用 \s 进行替换,我使用 ' '。所以正则表达式变为:
$string = s/\s+/ /g;
为什么带有 \s 的正则表达式不起作用?
\s只是正则表达式中的元字符(它不仅匹配空格,例如制表符、换行符和换页符),而不是替换字符串。如果您想用一个空格替换所有空格,请使用一个简单的空格(就像您已经做过的那样):
$string = s/\s+/ /g;
如果您只想影响实际的空格字符,请使用
$string = s/ {2,}/ /g;
(无需用自己替换单个空格)。
您的问题的答案是这\s是一个字符类,而不是文字字符。就像\w表示字母数字字符一样,它不能用于打印字母数字字符(除了w,它将打印,但这不是重点)。
如果我想保留匹配的空白类型,我会做的是:
s/\s\K\s*//g
( \Kkeep) 转义序列将保持初始空白字符不被删除,但所有后续空格都将被删除。如果您不关心保留空格的类型,则 Tim 已经给出的解决方案是可行的方法,即:
s/\s+/ /g
为什么带有 \s 的正则表达式不起作用?
您的正则表达式\s确实有效。不起作用的是您的替换字符串。当然,正如其他人指出的那样,它不应该。
人们对替换运算符 ( s/.../.../) 感到困惑。我经常发现人们将整个运算符视为“正则表达式”。但它不是,它是一个带有两个参数(或操作数)的运算符。
第一个操作数(在第一个和第二个分隔符之间)被解释为一个正则表达式。第二个操作数(在第二个和第三个定界符之间)被解释为双引号字符串(当然,/e选项会稍微改变)。
所以替换操作如下所示:
s/REGEX/REPLACEMENT STRING/
正则表达式识别特殊字符,如^and+和\s。替换字符串没有。
如果人们不再误解替换运算符是如何构成的,他们可能不再期望正则表达式功能在正则表达式之外工作:-)
\s代表匹配任何空格。这相当于:
[\ \t\r\n\f]
当您替换为 时$string = s/\s+/\s/g;,您将一个或多个空白字符替换为字母 s。这是一个参考链接:http: //perldoc.perl.org/perlrequick.html