在一行中删除重复的字符,包括空格

时间:2012-10-13 21:13:54

标签: regex perl


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

2 个答案:

答案 0 :(得分:3)

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

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

  • ^[\n\r]|\s匹配字符串开头的换行符或回车符,或任何位置的任何空格字符(这使得第一部分成为冗余,因为任何空格字符包含换行符和回车,任何地方包括字符串的开头。)

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

在角色类之外,^是一个锚点。


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

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

说明:

  • 由于您最终使用([.,])\1{1,},我认为您希望匹配重复的句号重复的逗号,而不是{{1} }或.,。正则表达式的成功意味着学习以正则表达式引擎的方式查看文本,并且它不直观。如果你尝试用正则表达式引擎的方式描述每个问题,如果它可以说话的话,你会自己帮助很多。

  • ,.不正确,但为什么{1,}执行同样的操作时,会将所有混乱添加到正则表达式中?

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

答案 1 :(得分:1)

您可以尝试使用: -

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,换行和换行。