我有一个perl正则表达式,我相当肯定应该工作(perl)但是太贪心了:
正则表达式:
(?:.*serial[^\d]+?(\d+).*)
测试字符串:
APPLICATIONSERIALNO123456Plnsn123456te20140728tdrnserialnun12hou
所需的第1组比赛:
123456
实际组1匹配:
12
我已经尝试了前瞻,背后和懒惰的每一种排列,我无法让这该死的事情发挥作用。
我错过了什么。
谢谢!
答案 0 :(得分:4)
目前,您的正则表达式与12
末尾的serialnun12
匹配,可能是因为它区分大小写。我们有两个选择:使用大写,或使模式不区分大小写。
选项1:使用大写
如果仅想要123456
,您可以使用:
SERIALNO\K\d+
\K
告诉引擎放弃与其返回的最终匹配相匹配的内容。
如果要匹配整个字符串并将123456
捕获到组1,请使用:
.*?SERIAL\D+(\d+).*
选项2:在使用(?i)
内嵌或i
标记
要仅匹配123456
,您可以使用:
(?i)serial\D+\K\d+
请注意,如果您使用g
标记,则会匹配这两个数字。
如果要匹配整个字符串并将123456
捕获到组1,请使用:
(?i).*?serial\D+(\d+).*
一些提示
(?i)
内联修饰符或模式末尾的i
标记来区分不区分大小写:/serial\D+\K\d+/i
[^\d]
\D
\D+\d+
之类的内容中不需要延迟量词,因为这两个令牌是相互排斥的:\D
不会超过\d
答案 1 :(得分:3)
问题不是贪婪;它区分大小写。
目前,您的正则表达式与12
末尾的serialnun12
匹配,因为这些是serial
后的唯一数字。您想要关注SERIAL
。 S
和s
是不同的字符。
有两种解决方案。
使用模式中的大写字符。
my ($serial) = $string =~ /SERIAL\D*(\d+)/;
使用不区分大小写的匹配。
my ($serial) = $string =~ /serial\D*(\d+)/i;
可能没有必要这样做,但我想我会提到它以防万一。