在 perl 中,当前面至少有三个单词时匹配一个点

In perl match a dot when there're at least three words before it

我正在使用 (?<=(?:(?:\w|,|'){1,20} ){2}(?:\w|,|'){1,20} ?)\. 但它没有按预期工作:

use v5.35.2;
use warnings;
use strict;

my $str = shift // q{If you have to go. you go. That's no problem.}; 

my $regex = qr/(?<=(?:(?:\w|,|'){1,20} ){2}(?:\w|,|'){1,20} ?)\./;

my @all_parts = split $regex, $str;

say for@all_parts;

它应该打印出 If you have to go you go. That's no problem

有没有更简单的方法来实现这个?

#!/usr/bin/env perl
use warnings;
use strict;
use feature qw/say/;

my $str = shift // q{If you have to go. you go. That's no problem.}; 
my $regex = qr/(?:\b[\w,']+\s*){3}\K\./; 
my @all_parts = split $regex, $str;
say for @all_parts;

随心所欲地分裂。使用 \K 丢弃实际匹配期间之前的所有内容是关键位。 (可能会对 RE 进行一些调整,以更好地解决您在示例字符串中未提供的边缘情况)。

split / [\w'] (?: [\s,]+ [\w']+ ){2} \K \. /x

备注:

  • 通常使用 \K 比回溯更容易和更有效。它还有一个优势,可以比真正的可变长度后视可以回溯的 255 个字符回溯得更远。但它的缺点是不能比上一场比赛结束时“回头看”得更远。这不是问题。
  • 请随意删除空格。如果这样做,您还可以删除 x.
  • 在每个现有的 + 之后添加一个 + 应该会使它更快一点。
  • 你明明认为a's是一个词,但前面的回答可以算作两个。例如,它认为 . 前面有 a's b. c.
  • 中的三个词