【问题标题】:In perl match a dot when there're at least three words before it在 perl 中,当它之前至少有三个单词时匹配一个点
【发布时间】:2021-11-17 12:55:26
【问题描述】:

我正在使用(?<=(?:(?:\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

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

【问题讨论】:

    标签: regex perl


    【解决方案1】:
    #!/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 进行一些调整,以更好地解决您在示例字符串中未提供的极端情况)。

    【讨论】:

    • 不起作用。拆分 a's b. c 即使它不应该因为 . 前面只有两个词。
    【解决方案2】:
    split / [\w'] (?: [\s,]+ [\w']+ ){2} \K \. /x
    

    注意事项:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-07-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-01
      • 2018-10-04
      • 1970-01-01
      相关资源
      最近更新 更多