2011-07-22 231 views

回答

1

這個問題可能是有趣:Perl regex replace count

你可能會做這樣的事情:

use strict; 
use warnings; 

my $count = 3; 
my $str = "blublublublublu"; 
$str =~ s/(lu)/--$count == 0 ? "LA":$1/ge; 
print $str; 
+0

或's/lu/- $ count == 0? 「LA」:$&/ ge' –

1

試試這個:

s/(sub-string{2,2})sub-string/$1new-string/ 

根據自己的需要調整2(這是你的「N'1)。請注意,這些子字符串之間可能不存在分隔符。例如「ABCABCABC」的工作,但「abcdefabcabc」不會

3

對於更換使用sed字符串的第n次出現,你可以使用這個命令:

sed 's/find_string/replace_string/n' 

更換子,我們需要知道什麼你想替換。舉個例子。

+0

例如:字符串「香蕉來自香蕉樹」,在這個我想改變第二個「香蕉」到「香蕉」 – MuraliKrishna

+0

sed的/ bananas /香蕉/ 2'輸入文件 – cppcoder

+0

@cppcoder你知道嗎?是從末尾開始指定'n'的一種方式? (例如,從字符串的末尾替換第一個子字符串) –

1

試試這個:

s/((old-string).*?){2}\2/\1\1new-string/ 
+0

嘿約翰,感謝您的輸入,\ 2和\ 1在這裏做什麼 – MuraliKrishna

+0

@ user857223:\ 1捕獲外部'()'和\ 2捕獲舊-串。從左至右讀取捕獲數據:'(capture-one(capture-two))' –

+0

$ _ =「Muralikrishna muralikrishna muralikrishna」; s /((murali)。*?){2} \ 2/\ 1「murale」/ g; print「$ _ \ n」; 這裏我期待「Muralikrishna muralikrishna muralekrishna」 – MuraliKrishna

1

你也可以這樣做

​​
+1

'$ ++ i'? 。 。 。 。 –

+0

@ socket-puppet:謝謝,我錯過了。顯然它是'++' – Dallaylaen

1

我真的相信,沒有必要在正則表達式中增加額外的複雜性,除非真的有必要這麼做(或者除非你只是玩得開心)。在代碼中,我竟打算用我會保持它的簡單,就像這樣:

my $string = "one two three four five"; 

$string =~ m/\w+\s*/g for 1 .. 2; 
substr($string,pos($string)) =~ s/(\w+)/3/; 
print "$string\n"; 

在標量上下文使用m//g使其每for循環迭代一次匹配。在每次迭代中,pos()都會跟蹤$string上最近的子匹配的結束。一旦你經歷了「n」次迭代(在這種情況下是兩次),你可以將pos()插入substr()。使用substr($string...作爲左值。它會限制正則表達式匹配從第二個參數中的任何位置開始。我們在那裏插入pos,這限制了它在最後一場比賽停止的情況下繼續進行下一場比賽。

這種方法消除了顯式的計數器(雖然for循環本質上是一樣的東西,沒有命名計數器變量)。這種方法也比s//condition ? result : result/eg的方法更好,因爲它會在第三次匹配完成後停止,而不是繼續嘗試匹配,直到達到可能的大字符串的末尾。換句話說,這種方法不會限制匹配,它只會有條件地處理任意數量的成功匹配的結果。

在上一個關於同一主題的問題中,我曾經在s ///運算符的左側嵌入了一個計數器。雖然它適用於特定情況,但它不是理想的解決方案,因爲它很容易被回溯所拋棄。這是另一種簡單的方法,那就是最好的方法。我在這裏提到它,這樣你就可以避免嘗試這種伎倆的誘惑(除非你想用回溯來獲得樂趣)。

我在這裏發佈的方法,我相信很清楚;你看看它,知道發生了什麼:比賽兩次,跟蹤上一場比賽的位置,現在第三次與替補比賽。你可以聰明,你可以有效率,並且你可以清楚。但有時你不能擁有三個。在這裏你可以高效,清晰。

+0

儘管這種方法不能用於所有模式,就像'(<= a)b'。 –

+0

您還需要確保'$ string'至少包含3次出現(如果任何m {...}失敗,則取消)。 –