如何在perl中使用正则表达式匹配两个实例并替换第一个实例?

发布于 2024-12-21 06:59:41 字数 394 浏览 3 评论 0原文

如果返回两个匹配项,我只想替换第一个实例。

示例:

$sen = "The quick brown fox jump over the lazy dog, fox is quick";

我怎样才能只匹配第一个fox并将其替换为wolf,反之亦然。

输出:

The quick brown wolf jump over the lazy dog, fox is quick 

或:

The quick brown fox jump over the lazy dog, wolf is quick 

谢谢。

I want to replace only the first instance if two matches returned.

example:

$sen = "The quick brown fox jump over the lazy dog, fox is quick";

how can i match only the first fox and replace it with wolf and vice versa.

Output:

The quick brown wolf jump over the lazy dog, fox is quick 

or:

The quick brown fox jump over the lazy dog, wolf is quick 

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

橙味迷妹 2024-12-28 06:59:41

使用全局选项 /g 对匹配进行计数,将匹配列表分配给空列表以获取计数(比临时变量更好)。第一次更换是基本的。第二个使用计数器,该计数器在每次匹配时递增,并在适当的时间替换。

注意使用单词边框\b来防止错误匹配,例如firefoxfoxy lady等。

代码:

use strict;
use warnings;
use v5.10;   # only required for say, use print instead if your version is lower

my $fox  = 'fox';
my $wolf = 'wolf';
my $sen = "The quick brown fox jump over the lazy dog, fox is quick";

if ((()=$sen =~ /\b$fox\b/g) == 2) {   # counting matches 
    my $first = $sen;
    $first =~ s/\b$fox\b/$wolf/;       # replacing first
    my $second = $sen;
    my $i = 0;
    $second =~ s/\b$fox\b/ ++$i == 2 ? $wolf : $fox/eg;  # replacing second
    say for $first, $second;
}

输出:

The quick brown wolf jump over the lazy dog, fox is quick
The quick brown fox jump over the lazy dog, wolf is quick

如果您想要更可重用的代码,您可以用它制作一个子例程。

my $second = replace_nr($sen, $fox, $wolf, 2);
...
sub replace_nr {
    my ($str, $find, $replace, $num) = @_;
    my $i = 0;
    $str =~ s/\b($find)\b/ ++$i == $num ? $replace : $find/eg;
    return $str;
}

然后你甚至可以使用 sub 来进行这两种替换:

my $first  = replace_nr($sen, $fox, $wolf, 1);
my $second = replace_nr($sen, $fox, $wolf, 2);

Counting matches by using global option /g, assign list of matches to an empty list to get a count (better than a temp variable). First replace is basic. Second uses a counter that increments for each match, and replaces at the proper time.

Note use of word border \b to prevent false matches, such as firefox, foxy lady, etc.

Code:

use strict;
use warnings;
use v5.10;   # only required for say, use print instead if your version is lower

my $fox  = 'fox';
my $wolf = 'wolf';
my $sen = "The quick brown fox jump over the lazy dog, fox is quick";

if ((()=$sen =~ /\b$fox\b/g) == 2) {   # counting matches 
    my $first = $sen;
    $first =~ s/\b$fox\b/$wolf/;       # replacing first
    my $second = $sen;
    my $i = 0;
    $second =~ s/\b$fox\b/ ++$i == 2 ? $wolf : $fox/eg;  # replacing second
    say for $first, $second;
}

Output:

The quick brown wolf jump over the lazy dog, fox is quick
The quick brown fox jump over the lazy dog, wolf is quick

If you wish a more reusable code, you can make a subroutine out of it.

my $second = replace_nr($sen, $fox, $wolf, 2);
...
sub replace_nr {
    my ($str, $find, $replace, $num) = @_;
    my $i = 0;
    $str =~ s/\b($find)\b/ ++$i == $num ? $replace : $find/eg;
    return $str;
}

You could then even use the sub for both substitutions:

my $first  = replace_nr($sen, $fox, $wolf, 1);
my $second = replace_nr($sen, $fox, $wolf, 2);
故笙诉离歌 2024-12-28 06:59:41

检查是否有(至少)两个并替换第一个:

# The quick brown *wolf* jump over the lazy dog, fox is quick
s/fox(?=.*fox)/wolf/s;

检查是否有(至少)两个并替换第二个:

# The quick brown fox jump over the lazy dog, *wolf* is quick:
s/fox.*\Kfox/wolf/s;

s/(fox.*)fox/${1}wolf/s;  # Slower, but works pre 5.10

To check if there are (at least) two and replace the first:

# The quick brown *wolf* jump over the lazy dog, fox is quick
s/fox(?=.*fox)/wolf/s;

To check if there are (at least) two and replace the second:

# The quick brown fox jump over the lazy dog, *wolf* is quick:
s/fox.*\Kfox/wolf/s;

s/(fox.*)fox/${1}wolf/s;  # Slower, but works pre 5.10
疯了 2024-12-28 06:59:41

默认情况下,替换运算符的作用正是:匹配并替换第一次出现的情况。

以下语句将为您提供第一条输出行:

s/wolf/fox/

By default, the substitution operator does exactly that: match and replace the first occurence.

The following statement will get you your first output line:

s/wolf/fox/
囚你心 2024-12-28 06:59:41

您的新问题是您想要计数

my $count = () = $text =~ /fox/g;

并替换第 N 个实例

my $n = 3;
my $nm1 = $n-1;
$text =~ s/(?:fox.*){$nm1}\Kfox/s;

Your new question is that you want the count

my $count = () = $text =~ /fox/g;

and to replace the Nth instance

my $n = 3;
my $nm1 = $n-1;
$text =~ s/(?:fox.*){$nm1}\Kfox/s;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文