如何使用正则表达式限制在 perl 上找到的匹配项?

发布于 2024-12-15 04:40:46 字数 529 浏览 0 评论 0原文

在对这个问题进行了大量研究之后,我来请求您的帮助:

我正在尝试限制 Perl 正则表达式对大文本所做的替换的重复。 我在 Google 中搜索并发现格式为 {2,3} (最小值,最大值),但这似乎与我使用的语法不同。

$replaced=~s/$var/$var2/g; # replaces all ocurrences
$replaced=~s/$var/$var2/;  # replaces only first one

我的非最佳解决方案:

for($i=0; $i<8; $i++){

    $replaced=~s/$var/$var2/;
}

我尝试过的:

$replaced=~s/$var/$var2/{8};
$replaced=~s/$var/$var2{8}/;

任何帮助将不胜感激!

编辑: 好吧,几乎必须涉及一个循环,呵呵..没有内置参数来限制它,这不是很奇怪吗?

I come to ask for your aid after a lot of research on this matter:

I'm trying to limit the repetition of the substitutions that a Perl regex does on a big text.
I've searched in Google and found that the format is {2,3} (min, max) however this seems to be for a different way that the syntax I'm using.

$replaced=~s/$var/$var2/g; # replaces all ocurrences
$replaced=~s/$var/$var2/;  # replaces only first one

my non optimal solution:

for($i=0; $i<8; $i++){

    $replaced=~s/$var/$var2/;
}

What I have tried:

$replaced=~s/$var/$var2/{8};
$replaced=~s/$var/$var2{8}/;

Any help will be appreciated!

edit:
OK so pretty much there has to be a loop involved huh.. isn't that weird that there is not a built in parameter to limit it??

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

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

发布评论

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

评论(3

只涨不跌 2024-12-22 04:40:46

\G 的答案可能是做你想做的事情的最实用的方法,但只是为了乐趣或启发或其他什么,这里是另一种方法(需要 perl 5.10 或更高版本),使用代码断言和回溯控制动词 (*COMMIT)(*FAIL)

my $str = "Bananas in pajamas are coming down the stairs";
my $limit = 3;
my $count;

$str =~ s/(*COMMIT)(?(?{ $count++ >= 3 })(*FAIL))a/A/g;
say $str;

仅在 $str 中留下文本“穿着睡衣的 BAnAnAs 正在下楼梯”前三个“a”受到影响,并且在第三个之后停止扫描字符串以查找更多匹配项。

The answers with \G are probably the most practical way to do what you want, but just for fun or edification or whatever, here is another way (requiring perl 5.10 or higher), using code assertions and the backtracking control verbs (*COMMIT) and (*FAIL):

my $str = "Bananas in pajamas are coming down the stairs";
my $limit = 3;
my $count;

$str =~ s/(*COMMIT)(?(?{ $count++ >= 3 })(*FAIL))a/A/g;
say $str;

which leaves the text "BAnAnAs in Pajamas are coming down the stairs" in $str — only the first three "a"s were affected and it stops scanning the string for more matches after the third.

彼岸花似海 2024-12-22 04:40:46

我对 Perl 不太熟悉,但我相信您想使用“\G 断言”(更多信息在这里),它将继续在上一场比赛结束的地方搜索新的比赛:

for($i=0; $i<8; $i++){

    $replaced=~s/\G$var/$var2/;
}

我不确定它是否实际上更有效,但它看起来确实像那是它的用途是什么...

I'm not fluent in Perl, but I believe you want to use the "\G Assertion" (more info here), which will continue searching for a new match at the place the previous match left off:

for($i=0; $i<8; $i++){

    $replaced=~s/\G$var/$var2/;
}

I'm not positive whether it is in fact more efficient, but it certainly seems like that's what it's intended for...

深者入戏 2024-12-22 04:40:46

答案:http://codenode. com/2010/06/24/single-pass-replace-with-perl-regex-g-anchor/

计数器修改摘录:

my $cnt = 0;
if ( $query =~ m/\bORDER BY /gi ) {
   while ($query =~ s/\G(.+?)\s+ASC/$1/gmsi && pos $query) {
       $cnt++; last if $cnt >= 8;
   }
}

Answer: http://codenode.com/2010/06/24/single-pass-replace-with-perl-regex-g-anchor/

Excerpt with modification for counter:

my $cnt = 0;
if ( $query =~ m/\bORDER BY /gi ) {
   while ($query =~ s/\G(.+?)\s+ASC/$1/gmsi && pos $query) {
       $cnt++; last if $cnt >= 8;
   }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文