Regex Perl正则表达式替换计数
是否可以指定要替换的最大匹配数。例如,如果在“Hello World”中匹配“l”,是否可以替换前2个“l”字符,但不能替换没有循环的第三个字符?简短回答:否。您需要在某种循环中执行替换。这里有一种方法。这需要在使用Regex Perl正则表达式替换计数,regex,perl,Regex,Perl,是否可以指定要替换的最大匹配数。例如,如果在“Hello World”中匹配“l”,是否可以替换前2个“l”字符,但不能替换没有循环的第三个字符?简短回答:否。您需要在某种循环中执行替换。这里有一种方法。这需要在使用(?(条件)真子表达式|假子表达式)构造内部的(?{code})块的情况下更新外部计数器。请参阅以获取解释 use Modern::Perl; use re qw/eval/; # Considered experimental. my $string = 'Hello world
(?(条件)真子表达式|假子表达式)
构造内部的(?{code})
块的情况下更新外部计数器。请参阅以获取解释
use Modern::Perl;
use re qw/eval/; # Considered experimental.
my $string = 'Hello world!';
my $count = 2;
my $re = qr/
(l)
(?(?{$count--})|(*FAIL))
/x;
say "Looking for $count instances of 'l' in $string.";
my ( @found ) = $string =~ m/$re/g;
say "Found ", scalar @found, " instances of 'l': @found";
输出为:
Looking for 2 instances of 'l' in Hello world!
Found 2 instances of 'l': l l
Found l at 3
Found l at 4
这里是对同一个regexp的另一个测试,但这次我们跟踪匹配的位置,只是为了证明它与前两次匹配
use Modern::Perl;
use strict;
use warnings;
use re qw/eval/; # Considered experimental.
my $string = 'Hello world!';
my $count = 2;
my $position = 0;
my $re = qr/
(l)(?{$position=pos})
(?(?{$count--})|(*FAIL))
/x;
while( $string =~ m/$re/g ) {
say "Found $1 at ", $position;
}
这次的输出是:
Looking for 2 instances of 'l' in Hello world!
Found 2 instances of 'l': l l
Found l at 3
Found l at 4
我不认为我会推荐这些。如果我考虑只将匹配约束到字符串的一部分,那么我将匹配字符串的substr()
。但是,如果你喜欢生活在边缘,那就去享受这段经历吧
这是一个替代品:
use Modern::Perl;
use strict;
use warnings;
use re qw/eval/; # Considered experimental.
my $string = 'Hello world!';
say "Before substitution $string";
my $count = 2;
my $re = qr/
(l)
(?(?{$count--})|(*FAIL))
/x;
$string =~ s/$re/L/g;
say "After substitution $string";
以及输出:
Before substitution Hello world!
After substitution HeLLo world!
我不明白循环有什么不好
实际上,这里有一个方法:
$str="Hello world!";
$str =~ s/l/$i++ >= 2 ? "l": "r"/eg;
print $str;
这是一个循环,因为当你这样做的时候,s///g是以一种循环的方式工作的。但这不是一个传统的循环。您可以使用python
re.sub(repl,string[,count=0])
,但这显然不是您所追求的。这可能是升级到python所需要的动机。@Quick:up?当然,你的意思是向下。我喜欢编写Perl,但我并不特别喜欢阅读它。注意:我真的很想通过YAPE::Regex::Explain来运行它,以显示发生了什么,但不幸的是,它没有生成对正在发生的事情的准确描述。另一条评论,如果有人还在读:任何包含嵌入在regexp本身中的计数器的方法都可能对RE引擎的回溯非常敏感。只是一个想法。@re=qw(l);s/(l)/shift@re | | | 1美元/加仑代码>这很可爱,但它的实用性在某种程度上仅限于最琐碎的正则表达式模式。你在答案中发布的版本更有用。后一种方式如何“循环”?它只遍历字符串一次,对吗?@Tim Nordenfur:每次找到匹配项时,它都会求值,但是的,只遍历字符串一次。你可以做while(/match/g)
来创建一个循环。每个方法都是一个循环。有显式循环(看起来像'while'或'foreach'的循环)和隐式循环(没有名称但发生在幕后的循环)。没有隐式循环就没有遍历(甚至一次)。它只是隐藏在RE引擎的/g子句中。