2012-10-13 73 views
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字符。有很多方法可以做到這一點,但這是我解決的問題。非常感謝!

回答

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,換行符和換行符。
+0

更新正則表達式,考慮時間也。錯過了。 –

+0

這是正確的 – shashuec

+0

這一個似乎也刪除\ r和\ n。不過,它工作得很好,但! – Thumper

3

這是大多Rohit's answer批判,這似乎包含有關字符類語法的幾個誤解,尤其是否定運算符(^)。具體做法是:

  • [(^\n^\r)\s]匹配(^)或任何空白字符,包括換行符(\n)和回車(\r)。實際上,他們每次都被指定了兩次(因爲\s也與他們相匹配),儘管這個職業每次只消耗一個角色。

  • ^[\n\r]|\s匹配字符串,或任何空白字符的任何地方(這使得第一部分冗餘的開始換行或回車,因爲任何空白字符包括換行和回車,任何地方包括字符串的開頭)。

在字符類中,插入符號(^)否定後面當且僅當它開幕[後立即顯示一切的意思;其他地方,它只是一個插入符號。除\之外的所有其他元字符在字符類中完全失去其特殊含義。 (但通常非特殊字符-]變得特別。)

在字符類外,^是一個錨點。


這是我會怎麼寫的正則表達式:

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

說明:

  • 既然你最後用([.,])\1{1,}去了,我想你想匹配週期重複重複逗號,而不是像.,,.。正則表達式的成功意味着學習如何使用正則表達式引擎來查看文本,這並不直觀。如果你試圖按照正則表達式引擎的方式來描述每個問題,那麼你會爲自己做很多事情,如果可以說話的話。

  • {1,}是不正確的,但是爲什麼當+做同樣的事情時將所有混亂添加到您的正則表達式?

  • \h匹配橫向空格,其中包含空格和製表符,但不包括換行符或回車符。 (這僅適用於Perl中,據我所知在Ruby/Oniguruma,\h一個十六進制數字相匹配;在所有其他的味道,我知道,這是一個語法錯誤。)

+0

@AlanMoore ..我沒有注意到這是發生在我的正則表達式。其實這是第一次爲我工作,所以發佈它..我已編輯它,以刪除錯誤的正則表達式。你可以看看並評論它是否正確? –

+0

@RohitJain:'[^ \ S \ r \ n]'可能夠好,但我會使用更準確和可讀的東西,比如'[\ x20 \ t]'或'\ h'。至於'[。,] {2,}',它匹配句點和逗號的混雜,我相信OP希望純粹運行一個或另一個。 –

+0

@AlanMoore ..謝謝Alan。在您提到之前我沒有聽說過\ \ h' .. –