我正在尝试编写一个正则表达式模式,该模式将捕获两个字符之间的子字符串。字符串是
default_checks/my_checks/VLG6.3: Unsupported system function call
我需要捕获VLG6.3
。它在斜杠/
和冒号:
之间。
我尝试了这些想法
my $rule = $line =~ /\/(.*)\:/;
my $rule = $line =~ /\/(.+?)\:/ ;
my $rule = $line =~ /\/(\w+)\:/ ;
但是它们都不起作用。最好的情况下,我得到my_checks/VLG6.3
答案 0 :(得分:3)
除了ikegami指出的给标量分配列表的问题外,regex模式还可以使用一些固定方法。
正则表达式中的转发器*
是贪婪的。只要匹配,它就会吞噬尽可能多的字符。您需要让另一个中继器预先进行吞噬,以便仅留给您真正想要匹配的中继器。
my ($rule) = $line =~ /.*\/(.*):/;
或者,在这种情况下,您可以使用排除类而不是匹配任何字符。
my ($rule) = $line =~ /\/([^\/]*):/;
以上两种情况都将以$rule
分配给'VLG6.3'
来结束。
答案 1 :(得分:2)
您对满足以下条件的非空字符串感兴趣:
/
。/
,也不包含冒号。因此,没有任何捕获组的直观正则表达式为:
(?<=\/)[^\/:]+(?=:)
(正向后看,实际内容
和积极向前看。
使用这样的正则表达式,您可以:
=~
运算符的结果 来检查是否已
匹配。$&
变量中打印匹配的文本。示例脚本如下所示:
use strict;
use warnings;
my $line = 'default_checks/my_checks/VLG6.3: Unsupported system function call';
print "Source: $line\n";
if ($line =~ /(?<=\/)[^\/:]+(?=:)/) {
print "Rule: $&\n";
} else {
print "No match.\n";
}
答案 2 :(得分:1)
获得1
的原因是因为您正在标量上下文中评估匹配项。为了使匹配返回捕获结果,需要在列表上下文中对其进行评估。
您需要通过在列表上下文中评估=~
来评估列表上下文中的匹配项。与您使用的标量赋值运算符不同,列表赋值运算符在列表上下文中评估其操作数。通过将my $rule
替换为my ($rule)
,可以使列表赋值运算符被使用。
my ($rule) = $line =~ /\/(.*)\:/;
此外,匹配运算符将抓取更多的期望值。您可以通过替换
来解决/\/(.*)\:/
使用
/\/([^\/]*)\:/
我将这样写:
m{/([^/]*):}
答案 3 :(得分:0)
要捕获两个字符之间的字符串,请捕获非两个字符的所有内容。
my $line = 'default_checks/my_checks/VLG6.3: Unsupported system function call';
my ( $rule ) = $line =~ /\/([^\/:]*):/;
print "$rule\n";
PS:要捕获两个字符串之间的内容,需要跳过起始字符串的序列。
my $line = 'begin not this begin or this begin wanted end not this end or this end';
my ( $rule ) = $line =~ m{ (?: begin .* )? begin (.*?) end }msx;
print "$rule\n";