Perl替换字符串中的第n个子字符串

时间:2011-07-22 04:10:11

标签: regex perl

我有一个场景,我需要在字符串中替换第n个子字符串。

s/sub-string/new-string/g;将替换所有子字符串,但我需要为特定事件做。

请帮助我。

6 个答案:

答案 0 :(得分:3)

要使用sed替换第n个字符串,可以使用以下命令:

sed 's/find_string/replace_string/n'

要替换子字符串,我们需要知道要替换的内容。举个例子。

答案 1 :(得分:1)

试试这个:

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

根据您的需要调整2(这是你的'n'-1)。请注意,这些子串之间可能不存在分隔符。例如'abcabcabc'会起作用,但'abcdefabcabc'不会

答案 2 :(得分:1)

试试这个:

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

答案 3 :(得分:1)

您也可以这样做

my $i=0;
s/(old-string)/++$i%3 ? $1 : "new_string"/ge;

答案 4 :(得分: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;

答案 5 :(得分: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...作为左值。它会限制正则表达式匹配从你在第二个arg中调用它的任何位置开始。我们在那里插入了pos,这限制了它在最后一场比赛停止的地方进行下一场比赛。

这种方法消除了显式计数器(尽管for循环基本上是相同的,没有命名计数器变量)。这种方法也比s//condition ? result : result/eg方法更好地扩展,因为它将在第三次匹配完成后停止,而不是继续尝试匹配,直到达到潜在的大字符串结束。换句话说,s///eg方法不会限制匹配,它只会有条件地处理任意大量成功匹配的结果。

在上一个关于同一主题的问题中,我曾经在s ///运算符的左侧嵌入了一个计数器。虽然它适用于特定情况,但它并不是一个理想的解决方案,因为它很容易因回溯而被抛弃。这是保持简单的另一种情况,这是最好的方法。我在这里提到它,这样你就可以避免试图尝试这样的技巧(除非你想通过回溯获得乐趣)。

我在这里发布的方法,我相信非常清楚;你看看它并知道发生了什么:匹配两次,跟踪最后一个匹配位置,现在匹配第三次替换。你可以聪明,你可以有效率,你可以有明确的。但有时你不能拥有这三个。在这里,您将获得高效和清晰的信息。