我想要一个匹配某行开头的正则表达式,然后匹配(并返回)所有其他单词。例如,给定这一行:
$line = "one two three etc";
我想要这样的东西(这不起作用):
@matches= $line=~ /^one(?:\s+(\S+))$/;
返回@matches,单词" two"," three"," etc"。
我不想知道如何得到这些话。我想用正则表达式来做。看起来很简单,但我无法找到解决方案。
答案 0 :(得分:4)
您不能拥有未知数量的捕获组。如果您尝试重复捕获组,则最后一个实例将覆盖捕获组的内容:
^one(?:\s+(\S+))+$
etc
或者:
^one\s+(\S+)\s+(\S+)\s+(\S+)$
two
three
etc
我建议捕获整个组,然后按空格分割:
^one\s+((?:\S+\s*)+)$
two three etc
或者您可以进行全局匹配并使用\G
和\K
:
(?:^one|(?<!\A)\G).*?\K\S+
two
three
etc
答案 1 :(得分:4)
答案 2 :(得分:0)
为此,您需要使用与最后一场比赛结束时的位置相匹配的\G
锚点。使用此锚点构建模式时,可以获得连续的结果:
@matches = $line =~ /(?:\G(?!\A)|^one) (\S+)/g;
答案 3 :(得分:-1)
在事实之后,最简单的解决方案可能是split
:
use strict;
use warnings;
my $line = "one two three etc";
my @matches = $line =~ /^one\s+(.*)/ ? split(' ', $1) : ();
use Data::Dump;
dd @matches;
输出:
("two", "three", "etc")
但是,也可以使用\G
继续前一个匹配的位置,从而使用/g
修饰符找到所有非空格。
唯一的诀窍是记住不要让\G
在字符串的开头匹配,这样单词one
必须匹配:
my @matches = $line =~ /(?:^one|(?<!\A)\G)\s+(\S+)/g;