我需要一个正则表达式,它匹配一行开头的某个单词,然后匹配(并返回)所有其他单词。例如,给定下面这行:
$line = "one two three etc";
我想要这样的东西(不工作):
@matches= $line=~ /^one(?:\s+(\S+))$/;
为了返回到@匹配,单词“two”、“three”、“etc”。我不想知道如何得到单词。我想用一个正则表达式来做。它看起来很简单,但我一直没有能想出一个解决方案。
5lhxktic1#
要做到这一点,你需要使用\G锚来匹配最后一个匹配的结尾位置。当你用这个锚点构建一个模式时,你可以获得连续的结果:
\G
@matches = $line =~ /(?:\G(?!\A)|^one) (\S+)/g;
wixjitnu2#
捕获组的数目不能未知。如果尝试重复捕获组,则最后一个示例将覆盖捕获组的内容:
^one(?:\s+(\S+))+$
etc
或者:
^one\s+(\S+)\s+(\S+)\s+(\S+)$
two
three
我建议捕获整个组,然后按空格拆分:
^one\s+((?:\S+\s*)+)$
two three etc
或者,您可以执行全局匹配并利用\G和\K:
\K
(?:^one|(?<!\A)\G).*?\K\S+
drkbr07n3#
^.*?\s\K|(\w+)
试试这个。看演示。http://regex101.com/r/lS5tT3/2
9ceoxa924#
(?{...})“执行代码”特殊分组可用于记忆必要的中间分组捕获让我们从您的代码开始:
#!/usr/bin/perl $line = "one two three etc"; @matches = (); $line=~ /^one(?:\s+(\S+)(?{push @matches, $1}))+$/; print join "\n", @matches;
@matches数组中包含“two”、“three“等。因为在部分匹配后执行的(?{push @matches,$1})会将捕获的值存储在这里。更复杂的例子可以更好地阐明这种方法:
#!/usr/bin/perl while(<>) { $a .= $_; } $a =~ m{cipher-suites:\s*\[[\r\n" ]+(?:([^\]]*?)[\r\n", ]+(?{push @r, $1}))+\]}sm; print join "\n", @r; __END__ cipher-suites: [ "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256" ]
这会将密码提取到数组@r中(?{...})“execute code”是一个非常强大的正则表达式扩展,例如,它可以扩展正则表达式,使其可以匹配嵌套的括号表达式。
klr1opcd5#
最简单的解决办法可能是事后对split:
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就必须匹配:
/g
one
my @matches = $line =~ /(?:^one|(?<!\A)\G)\s+(\S+)/g;
5条答案
按热度按时间5lhxktic1#
要做到这一点,你需要使用
\G
锚来匹配最后一个匹配的结尾位置。当你用这个锚点构建一个模式时,你可以获得连续的结果:wixjitnu2#
捕获组的数目不能未知。如果尝试重复捕获组,则最后一个示例将覆盖捕获组的内容:
^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
drkbr07n3#
试试这个。看演示。
http://regex101.com/r/lS5tT3/2
9ceoxa924#
(?{...})“执行代码”特殊分组可用于记忆必要的中间分组捕获
让我们从您的代码开始:
@matches数组中包含“two”、“three“等。因为在部分匹配后执行的(?{push @matches,$1})会将捕获的值存储在这里。
更复杂的例子可以更好地阐明这种方法:
这会将密码提取到数组@r中
(?{...})“execute code”是一个非常强大的正则表达式扩展,例如,它可以扩展正则表达式,使其可以匹配嵌套的括号表达式。
klr1opcd5#
最简单的解决办法可能是事后对
split
:输出:
但是,也可以使用
\G
从上一个匹配中断的地方继续,从而使用/g
修饰符找到所有非空格。唯一的技巧是记住不要让
\G
在字符串的开头匹配,这样单词one
就必须匹配: