如何搜索和替换多次出现的单词

How to search and replace a word on multiple occurrence

谁能告诉我如何使用 perl 脚本在文本文件中搜索单词并将前 2 次出现的值替换为一个值,接下来的 2 次出现的值替换为另一个值等等?那可能吗?下面的命令只是将所有 cat1、cat2、cat3 等替换为 dog1,但我想将 cat1、cat2 替换为 dog1,将 cat3、cat4 替换为 dog3。

s/cat[0-9]/dog1/g;

下面是我试过的脚本:

#!/usr/bin/perl -w

use strict;

my $file = 'C:\Temp\test.txt';
rename($file, $file . '.bak');
open(IN, '<' . $file . '.bak') or die $!;
open(OUT, '>' . $file) or die $!;
while(<IN>)
{
    $_ =~ s/cat[0-9]/dog1/g;
    print OUT $_;
}
close(IN);
close(OUT);

输入:

Replacement value1: dog51
Replacement value2: dog23
Replacement value3: dog77
Replacement value4: dog95

现有文件:

<some texts>
test cat01 text
test cat32 text
test cat83 text
test cat54 text
test cat92 text
test cat13 text
test cat62 text
test cat23 text

替换后的文件:

<some texts>
test dog51 text
test dog51 text
test dog23 text
test dog23 text
test dog77 text
test dog77 text
test dog95 text
test dog95 text

参考s///(尤其是e修饰符)。这将用 N-1 替换偶数。

use warnings;
use strict;

while (<DATA>) {
    s/cat(\d+)/sprintf 'dog%0d', ( % 2) ?  : (-1)/e;
    print;
}

__DATA__
cat1
cat2
cat3
cat4
cat5
cat6

打印:

dog1
dog1
dog3
dog3
dog5
dog5

(\d+) 捕获 cat 之后的数字并将它们存储在替换右侧使用的 </code> 变量中。</p> <hr /> <p>问题更新后,看起来替换值应该是随机的:</p> <pre><code>use warnings; use strict; my $cnt = 0; my $n; while (<DATA>) { if (/cat\d/) { $cnt = ($cnt) ? 0 : 1; $n = randint() if $cnt; s/cat(\d+)/dog$n/; } print; } sub randint { return sprintf '%02d', int rand 100; } __DATA__ test cat01 text test cat32 text test cat83 text test cat54 text test cat92 text test cat13 text test cat62 text test cat23 text

打印:

test dog38 text
test dog38 text
test dog46 text
test dog46 text
test dog98 text
test dog98 text
test dog59 text
test dog59 text

每次代码为 运行 时,将显示一组不同的数字。

根据 OP,输入和输出编号没有相关性。

在这种情况下,可能的解决方案是将输入值哈希映射到输出值

use strict;
use warnings;

my %hash = (
        'cat1' => 'dog1',
        'cat2' => 'dog1',
        'cat3' => 'dog3',
        'cat4' => 'dog3'
    );

while( my $line = <DATA> ) {
    $line =~ s/\b($_)\b/$hash{}/g for keys %hash;
    print $line;
}

__DATA__
some sentence cat1 goes here
some cat3 sentence goes here
some sentence goes cat1 here
some sentence cat34 goes here
cat4 some sentence goes here

输出

some sentence dog1 goes here
some dog3 sentence goes here
some sentence goes dog1 here
some sentence cat34 goes here
dog3 some sentence goes here

预定义双重替换的示例代码(用于更改问题中的问题描述)

use strict;
use warnings;

my($index,$counter) = (-1,-1);

my @input = (
        'Replacement value1: dog51',
        'Replacement value2: dog23',
        'Replacement value3: dog77',
        'Replacement value4: dog95'
    );
    
@input = map { s/Replacement value\d: // && $_ } @input;

while( my $line = <DATA> ) {
    if( $line =~ /cat\d{2}/ ) {
        ++$index unless ++$counter%2;
        $line =~ s/\bcat\d{2}\b/$input[$index]/;
    }
    print $line;
}

__DATA__
<some texts>
test cat01 text
test cat32 text
test cat83 text
test cat54 text
test cat92 text
test cat13 text
test cat62 text
test cat23 text
<some text>

输出

<some texts>
test dog51 text
test dog51 text
test dog23 text
test dog23 text
test dog77 text
test dog77 text
test dog95 text
test dog95 text
<some text>