正则表达式问题:为什么这不匹配?
Regex trouble: Why does this not match?
我需要一个始终匹配 (!) 的正则表达式来提取 Postgresql 中的数据(使用 regexp_matches)。
这是一个示例输入:
#link showcatalog=123 text=blurb
我的正则表达式:
/(?:showcatalog=([0-9]+))?/
我用 Perl 试过这个:
perl -e 'use Data::Dumper; print Dumper([ "#link showcatalog=123 text=blurb" =~ /(?:showcatalog=([0-9]+))?/ ]);'
并期望 $VAR1 = [ 123 ]
但得到了 $VAR1 = [ undef ]
。我不明白,因为“?”是贪婪的,而且它的行为不是这样的。我有什么不明白的?我试过 regex101.com 但这对我没有帮助。如何得到预期的结果?
不是应该优先匹配文本吗,比较贪心?
如果没有,就去匹配,比如在
#link text=blurb"
我只想得到$VAR1 = [ undef ]
?
贪心是正确的,但是匹配零次或一次直到满足条件。贪心就是在这个"zero or one"条件下。在您的情况下,由于整个正则表达式是可选的(由 ?
包围),因此优先考虑 "zero" 时间,因为它是第一种可能性。
引擎一步步来,试图匹配你的表情。在字符串的第一个字符中,零匹配已经是可能的,因此不会返回任何内容。从这个意义上说,?
是贪婪的,如果零或一个是可能的(它将选择一个),但如果匹配已经满足,则返回它。贪婪并不优先于是否匹配整个表达式。如果是指:如果有取零或取一的可能。
你的 [0-9]
刚好 \d
。所以如果你需要提取数字你可以使用这个:
/showcatalog=(\d+)/
要提取整个文本(showcatalog
和数字)只需使用
/(showcatalog=\d+)/
类似于您的命令:
perl -e 'use Data::Dumper; print Dumper([ "#link showcatalog=123 text=blurb" =~ /showcatalog=(\d+)/ ]);'
在 Perl 脚本中:
my $string1 = "#link showcatalog=123 text=blurb";
my ($number1) = $string1 =~ /showcatalog=(\d+)/;
print Dumper([ $number1 ]);
my $string2 = "#link text=blurb";
my ($number2) = $string2 =~ /showcatalog=(\d+)/;
print Dumper([ $number2 ]);
你可以强制一个undef
出现,如果你使用像这样的东西:
/(?:.*showcatalog=(\d+))?/
问题是您只得到第一个匹配项,其中 (?:...)?
组是空的,这要归功于最后的 ?
。它可以匹配字符串中的任何位置;要查看所有可能的匹配项,请使用 /g
修饰符:
perl -e 'use Data::Dumper; print Dumper([ "#link showcatalog=123 text=blurb" =~ /(?:showcatalog=([0-9]+))?/g ]);'
$VAR1 = [
undef,
undef,
undef,
undef,
undef,
undef,
'123',
undef,
undef,
undef,
undef,
undef,
undef,
undef,
undef,
undef,
undef,
undef,
undef
];
你需要使用这个模式
/.*showcatalog=([0-9]+)|/
.*
强制回溯以在字符串中的任何位置查找 showcatalog=([0-9]+)
,并且 |
还允许空字符串匹配(它始终会匹配)如果第一个替代项失败,将 </code> 设置为 <code>undef
perl -MData::Dumper -e 'print Dumper [ "#link showcatalog=123 text=blurb" =~ /.*showcatalog=([0-9]+)|/ ]'
输出
$VAR1 = [
'123'
];
perl -MData::Dumper -e 'print Dumper [ "#link xxx=123 text=blurb" =~ /.*showcatalog=([0-9]+)|/ ]'
输出
$VAR1 = [
undef
];
我需要一个始终匹配 (!) 的正则表达式来提取 Postgresql 中的数据(使用 regexp_matches)。
这是一个示例输入:
#link showcatalog=123 text=blurb
我的正则表达式:
/(?:showcatalog=([0-9]+))?/
我用 Perl 试过这个:
perl -e 'use Data::Dumper; print Dumper([ "#link showcatalog=123 text=blurb" =~ /(?:showcatalog=([0-9]+))?/ ]);'
并期望 $VAR1 = [ 123 ]
但得到了 $VAR1 = [ undef ]
。我不明白,因为“?”是贪婪的,而且它的行为不是这样的。我有什么不明白的?我试过 regex101.com 但这对我没有帮助。如何得到预期的结果?
不是应该优先匹配文本吗,比较贪心?
如果没有,就去匹配,比如在
#link text=blurb"
我只想得到$VAR1 = [ undef ]
?
贪心是正确的,但是匹配零次或一次直到满足条件。贪心就是在这个"zero or one"条件下。在您的情况下,由于整个正则表达式是可选的(由 ?
包围),因此优先考虑 "zero" 时间,因为它是第一种可能性。
引擎一步步来,试图匹配你的表情。在字符串的第一个字符中,零匹配已经是可能的,因此不会返回任何内容。从这个意义上说,?
是贪婪的,如果零或一个是可能的(它将选择一个),但如果匹配已经满足,则返回它。贪婪并不优先于是否匹配整个表达式。如果是指:如果有取零或取一的可能。
你的 [0-9]
刚好 \d
。所以如果你需要提取数字你可以使用这个:
/showcatalog=(\d+)/
要提取整个文本(showcatalog
和数字)只需使用
/(showcatalog=\d+)/
类似于您的命令:
perl -e 'use Data::Dumper; print Dumper([ "#link showcatalog=123 text=blurb" =~ /showcatalog=(\d+)/ ]);'
在 Perl 脚本中:
my $string1 = "#link showcatalog=123 text=blurb";
my ($number1) = $string1 =~ /showcatalog=(\d+)/;
print Dumper([ $number1 ]);
my $string2 = "#link text=blurb";
my ($number2) = $string2 =~ /showcatalog=(\d+)/;
print Dumper([ $number2 ]);
你可以强制一个undef
出现,如果你使用像这样的东西:
/(?:.*showcatalog=(\d+))?/
问题是您只得到第一个匹配项,其中 (?:...)?
组是空的,这要归功于最后的 ?
。它可以匹配字符串中的任何位置;要查看所有可能的匹配项,请使用 /g
修饰符:
perl -e 'use Data::Dumper; print Dumper([ "#link showcatalog=123 text=blurb" =~ /(?:showcatalog=([0-9]+))?/g ]);'
$VAR1 = [
undef,
undef,
undef,
undef,
undef,
undef,
'123',
undef,
undef,
undef,
undef,
undef,
undef,
undef,
undef,
undef,
undef,
undef,
undef
];
你需要使用这个模式
/.*showcatalog=([0-9]+)|/
.*
强制回溯以在字符串中的任何位置查找 showcatalog=([0-9]+)
,并且 |
还允许空字符串匹配(它始终会匹配)如果第一个替代项失败,将 </code> 设置为 <code>undef
perl -MData::Dumper -e 'print Dumper [ "#link showcatalog=123 text=blurb" =~ /.*showcatalog=([0-9]+)|/ ]'
输出
$VAR1 = [
'123'
];
perl -MData::Dumper -e 'print Dumper [ "#link xxx=123 text=blurb" =~ /.*showcatalog=([0-9]+)|/ ]'
输出
$VAR1 = [
undef
];