我有一个像"ven|ven|vett|vejj|ven|ven"
这样的字符串。处理每列的每个"|"
分隔符。
将"|"
字符串拆分,保存数组中的所有列并将每列读入$str
所以,我试图这样做
$string =~ s/$str/venky/g if $str =~ /ven/i; # it will do globally.
哪个不符合要求。
按需,我需要在特定的字符串出现次数替换字符串。
例如,我发出了将"ven"
第二次更改为 venky 的请求。
那我怎么能简单地满足这个要求呢?是否有点像
$string =~ s/ven/venky/2;
据我所知,我们有' o'替换一次,' g'为了全球。我努力寻求解决方案,以便在特定情况下获得替代品。我不应该使用pos()
来获得这个位置,因为字符串会不断变化。每次都很难追踪它。这是我的意图。
请在这方面帮助我。
答案 0 :(得分:1)
没有可以添加到执行此操作的正则表达式的标记。
最简单的方法是拆分和循环。但是,如果你坚持使用一个正则表达式,它是可行的:
/^(?:[^v]|v[^e]|ve[^n])*ven(?:[^v]|v[^e]|ve[^n])*\Kven/
如果您想要替换 N 次而非第二次出现,您可以这样做:
/^(?:(?:[^v]|v[^e]|ve[^n])*ven){N-1}(?:[^v]|v[^e]|ve[^n])*\Kven/
总体思路:
(?:[^v]|v[^e]|ve[^n])*
- 匹配任何不属于ven
\K
是一个很酷的匹配器,可以删除到目前为止匹配的所有内容,因此您可以将其用作可变长度的后视镜
答案 1 :(得分:1)
目前,您正在更换&ven;' ven'与' venky'如果你的字符串包含ven
的匹配项,那当然就是这样。
我认为你要做的就是用“替代”来代替' ven'为了' venky'在你的字符串中,如果它是第二个元素:
my $string = 'ven|ven|vett|vejj|ven|ven';
my @elements = split(/\|/, $string);
my $count;
foreach (@elements){
$count++;
s/$_/venky/g if /ven/i and $count == 2;
}
print join('|', @elements);
print "\n";
答案 2 :(得分:1)
你的方法已经相当不错了。你所描述的是有道理的,但我认为你在实施它时遇到了麻烦。
我创建了一个功能来完成这项工作。它需要4个参数:
$string
是我们想要处理的字符串$n
是您要替换的 nth 出现 $needle
是您想要替换的东西 - 针在大海捞针中
请注意,现在我们允许传递可能包含正则表达式的内容。因此,您必须使用quotemeta
或与/\Q$needle\E/
$replacement
是$needle
想法是拆分字符串,然后检查每个元素是否与模式($needle
)匹配,并跟踪已匹配的数量。如果到达第n个,请更换它并停止处理。然后将琴弦放回原处。
use strict;
use warnings;
use feature 'say';
say replace_nth_occurance("ven|ven|vett|vejj|ven|ven", 2, 'ven', 'venky');
sub replace_nth_occurance {
my ($string, $n, $needle, $replacement) = @_;
# take the string appart
my @elements = split /\|/, $string;
my $count = 0; # keep track of ...
foreach my $e (@elements) {
$count++ if $e =~ m/$needle/; # ... how many matches we've found
if ($count == $n) {
$e =~ s/$needle/$replacement/; # replace
last; # and stop processing
}
}
# put it back into the pipe-separated format
return join '|', @elements;
}
<强>输出强>:
ven|venky|vett|vejj|ven|ven