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

neekobn8  于 2023-01-17  发布在  Perl
关注(0)|答案(7)|浏览(208)

我有一个需要替换字符串中第n个子字符串的场景。
s/sub-string/new-string/g;将替换所有的子字符串,但我需要在特定情况下这样做。
请帮我一下。

dluptydi

dluptydi1#

要使用sed替换第n次出现的字符串,可以使用以下命令:

sed 's/find_string/replace_string/n'

要替换子串,我们需要知道你想替换什么。给予个例子。

hm2xizp9

hm2xizp92#

这个问题可能很有趣:Perl regex replace count
你可以这样做:

use strict;
use warnings;

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

dldeef673#

试试这个:

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

根据您的需要调整2(它是您的'n'-1)。注意在这些子字符串之间可能没有分隔符。例如' abcabcabc '可以使用但' abcdefabcabc '不能

imzjd6km

imzjd6km4#

你也可以这样做

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

dw1jzc5e5#

我真的相信,除非真的有必要(或者除非你只是为了好玩),否则在正则表达式中构建额外的复杂性是没有意义的。在我实际计划使用的代码中,我会保持它的简单性,就像这样:

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...作为左值。它将约束regexp匹配从您在第二个参数中指定的任何位置开始。我们将在此处插入pos,这约束它从上一个匹配停止的地方进行下一个匹配。
此方法消除了显式计数器(尽管for循环本质上是相同的,只是没有指定计数器变量)。这种方法比s//condition ? result : result/eg方法伸缩性更好,因为它将在第三次匹配完成后停止,而不是继续尝试匹配,直到到达一个可能很大的字符串的末尾。换句话说,s///eg方法不约束匹配,它仅有条件地处理任意大量成功匹配的结果。
在前一个关于同一主题的问题中,我曾经在s///运算符的左侧嵌入了一个计数器,虽然它在那个特定的情况下有效,这不是一个理想的解决方案,因为它很容易被回溯所抛弃。这是另一种情况,保持它的简单性本来是最好的方法。我在这里提到它,以便您可以避免尝试这种技巧的诱惑(除非你想从回溯中获得乐趣)。
我在这里公布的方法,我相信是非常清楚的;你看着它就知道发生了什么匹配两次,跟踪上次匹配的位置,现在用替换匹配第三次。你可以有聪明,你可以有效率,你可以有清晰。但有时你不能三个都有。在这里你可以有效率和清晰。

tuwxkamq

tuwxkamq6#

试试这个:

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

nqwrtyyt7#

请参见@-@+的perlvar。

my $str= "one two three four five";
  if ( $str =~ /(?: (\w+) .*? ){3}/x ) {
    substr $str, $-[1], $+[1] - $-[1], "-c-e-n-s-o-r-e-d-";
  }
  print $str, "\n";

正则表达式找到第3个示例,并在$1中捕获其起始字。

相关问题