2011-07-22 191 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 {...}失败,则取消)。 –