3


我目前有一个字符串,比如说$line='55.25040882, 3,,,,,,',我想从中删除所有空格以及重复的逗号和句点。目前,我有:

    $line =~ s/[.,]{2,}//;
    $line =~ s/\s{1,}//;

正如我所得到的那样有效'55.25040882,3',但是当我尝试时

$line =~ s/[.,\s]{2,}//;

它拉出“,”并留下“,,,,,”。我想保留第一个逗号并去掉空格。
有没有办法用一行正则表达式优雅地做到这一点?如果我需要提供其他信息,请告诉我。

编辑:由于有很多解决方案,我决定用以下答案更新我的问题:

$line =~ s/([.,])\1{1,}| |\t//g;

这将删除所有重复的句点和逗号,删除所有空格和制表符,同时保留 \r 和 \n 字符。有很多方法可以做到这一点,但这是我解决的方法。非常感谢!

4

2 回答 2

3

这主要是对Rohit 的回答的批评,它似乎包含一些关于字符类语法的误解,尤其是否定运算符 ( ^)。具体来说:

  • [(^\n^\r)\s]匹配(or ^or )or 任何空白字符,包括换行符 ( \n) 和回车符 ( \r)。事实上,它们每个都被指定了两次(因为\s它们也匹配),尽管该类仍然一次只消耗一个字符。

  • ^[\n\r]|\s匹配字符串开头的换行符或回车符,或任何地方的任何空白字符(这使得第一部分变得多余,因为任何空白字符都包括换行符和回车符,并且任何地方都包括字符串的开头)。

在字符类中,插入符号 ( ^) 否定后面所有内容的含义,如果它紧接在开头之后出现[;在其他任何地方,它只是一个插入符号。所有其他元字符除了\完全在字符类中失去其特殊含义。(但通常非特殊字符-],变得特殊。)

在字符类之外,^是一个锚。


这是我编写正则表达式的方式:

$line =~ s/([.,])\1+|\h+//g;

解释:

  • 由于您最终选择了([.,])\1{1,},我假设您想要匹配重复的句点重复的逗号,而不是像.,or之类的东西,.。正则表达式的成功意味着学习以正则表达式引擎的方式查看文本,而且它并不直观。如果您尝试以正则表达式引擎的方式描述每个问题(如果它会说话的话),您会对自己有很大帮助。

  • {1,}不是不正确的,但是为什么在+做同样的事情时将所有这些混乱添加到您的正则表达式中呢?

  • \h匹配水平空格,包括空格和制表符,但不匹配换行符或回车符。(这只适用于 Perl,AFAIK。在 Ruby/Oniguruma 中,\h匹配一个十六进制数字;在我所知道的所有其他风格中,这是一个语法错误。)

于 2012-10-14T04:43:27.467 回答
2

您可以尝试使用:-

my $line='55.25040...882, 3,,,,,,';
$line =~ s/[^\S\n\r]|[.,]{2,}//g;  # Negates non-whitespace char, \n and \r
print $line

输出: -

55.25040882,3
  • [^\S\n\r]|[.,]{2,}-> 这意味着[^\S\n\r]要么[.,]{2,}
  • [.,]{2,}-> 这意味着替换,或者如果在同一行中.有多个。2
  • [^\S\n\r]-> 表示否定所有whitespace character、换行和换行。
于 2012-10-13T21:29:17.017 回答