【问题标题】:Removing repeated characters, including spaces, in one line删除一行中的重复字符,包括空格
【发布时间】:2012-10-14 15:26:52
【问题描述】:


我目前有一个字符串,比如$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 字符。有很多方法可以做到这一点,但这是我解决的方法。非常感谢!

【问题讨论】:

    标签: regex perl


    【解决方案1】:

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

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

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

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

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


    这是我将如何编写正则表达式:

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

    解释:

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

    • {1,} 并没有错,但是当+ 做同样的事情时,为什么还要在你的正则表达式中添加所有这些杂乱无章的东西呢?

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

    【讨论】:

    • @AlanMoore.. 我没有注意到我的正则表达式中发生了这种情况。实际上,这是第一次对我有用,所以发布了它。我已经编辑了它,以删除错误的正则表达式。能不能看看评论一下对不对??
    • @RohitJain: [^\S\r\n] 可能已经足够好了,但我会使用更准确和可读的东西,比如[\x20\t]\h。至于[.,]{2,},它匹配杂乱无章的句号和逗号,我相信 OP 想要其中一个或另一个的纯运行。
    【解决方案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、换行符和换行符。

    【讨论】:

    • 更新了正则表达式,也考虑了句点。错过了。
    • 这个似乎也删除了\r和\n。但是,它确实工作得很好!!
    • @Thumper 更新了正则表达式以考虑 \r\n
    • 试试这个:$line =~ s/[^\S\n\r]|[.,]{2,}//g;它将匹配除 \n 和 \r 之外的所有空格
    • @Shashwat 噢!那要好得多。将发布它。
    猜你喜欢
    • 2017-05-23
    • 2015-01-13
    • 2013-04-14
    • 1970-01-01
    • 2016-12-26
    • 1970-01-01
    • 2014-01-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多