1

我编写正则表达式来删除字符串中的多个空格。代码很简单:

my $string = 'A string has more than 1      space';
$string = s/\s+/\s/g;

但是,结果很糟糕:'Asstringshassmoresthans1sspace'。它用“s”字符替换每个空格。

有一个解决方法是代替使用 \s 进行替换,我使用 ' '。所以正则表达式变为:

$string = s/\s+/ /g;

为什么带有 \s 的正则表达式不起作用?

4

4 回答 4

7

\s只是正则表达式中的元字符(它不仅匹配空格,例如制表符、换行符和换页符),而不是替换字符串。如果您想用一个空格替换所有空格,请使用一个简单的空格(就像您已经做过的那样):

$string = s/\s+/ /g;

如果您只想影响实际的空格字符,请使用

$string = s/ {2,}/ /g;

(无需用自己替换单个空格)。

于 2013-07-17T16:34:03.983 回答
4

您的问题的答案是这\s是一个字符类,而不是文字字符。就像\w表示字母数字字符一样,它不能用于打印字母数字字符(除了w,它将打印,但这不是重点)。

如果我想保留匹配的空白类型,我会做的是:

s/\s\K\s*//g

( \Kkeep) 转义序列将保持初始空白字符不被删除,但所有后续空格都将被删除。如果您不关心保留空格的类型,则 Tim 已经给出的解决方案是可行的方法,即:

s/\s+/ /g
于 2013-07-17T16:46:41.517 回答
1

为什么带有 \s 的正则表达式不起作用?

您的正则表达式\s确实有效。不起作用的是您的替换字符串。当然,正如其他人指出的那样,它不应该。

人们对替换运算符 ( s/.../.../) 感到困惑。我经常发现人们将整个运算符视为“正则表达式”。但它不是,它是一个带有两个参数(或操作数)的运算符。

第一个操作数(在第一个和第二个分隔符之间)被解释为一个正则表达式。第二个操作数(在第二个和第三个定界符之间)被解释为双引号字符串(当然,/e选项会稍微改变)。

所以替换操作如下所示:

s/REGEX/REPLACEMENT STRING/

正则表达式识别特殊字符,如^and+\s。替换字符串没有。

如果人们不再误解替换运算符是如何构成的,他们可能不再期望正则表达式功能在正则表达式之外工作:-)

于 2013-07-18T13:00:17.530 回答
1

\s代表匹配任何空格。这相当于:

[\ \t\r\n\f]

当您替换为 时$string = s/\s+/\s/g;,您将一个或多个空白字符替换为字母 s。这是一个参考链接:http: //perldoc.perl.org/perlrequick.html

于 2013-07-17T16:34:44.290 回答