我需要一个始终匹配(!)正则表达式来提取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 ]
答案 0 :(得分:3)
问题是,您只获得了第一场比赛,(?:...)?
组由于最终?
而为空。它可以匹配字符串中的任何位置;要查看所有可能的匹配项,请使用/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
];
答案 1 :(得分:2)
您需要使用此模式
/.*showcatalog=([0-9]+)|/
.*
强制回溯在字符串中的任何位置查找showcatalog=([0-9]+)
,|
也允许空字符串匹配(如果第一个选项失败,它将始终匹配)将$1
设置为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
];
答案 2 :(得分:1)
?
贪婪是正确的,但它会匹配零次或一次,直到条件满足为止。贪婪是在这种“零或一”的条件下。在您的情况下,由于整个正则表达式是可选的(由?
包围),因此它是第一种可能性,因此优先考虑“零”次。
引擎一步一步地尝试匹配你的表达。在字符串的第一个字符中,零匹配已经可以,因此不会返回任何内容。从这个意义上讲,?
是贪婪的,如果零或一个可能(它会选择一个),但如果匹配已经满足,则返回。贪婪并不优先于匹配整个表达式。如果指的是:如果有可能采取零或一采取一个。
您的[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+))?/