为什么\d+不能匹配所有数字?

5
我有以下正则表达式:
REGEX = /^.+(\d+.+(?=AL|AK|AS|AZ|AR|CA|CO|CT|DE|DC|FM|FL|GA|GU|HI|ID|IL|IN|IA|KS|KY|LA|ME|MH|MD|MA|MI|MN|MS|MO|MT|NE|NV|NH|NJ|NM|NY|NC|ND|MP|OH|OK|OR|PW|PA|PR|RI|SC|SD|TN|TX|UT|VT|VI|VA|WA|WV|WI|WY)[A-Z]{2}[, ]+\d{5}(?:-\d{4})?).+/

我有以下字符串:
str = "fdsfd 8126 E Bowen AVE Bensalem, PA 19020-1642 dfdf"

注意我的捕获组以一个或多个与模式匹配的数字开头。然而,这就是我得到的结果:
str =~ REGEX
$1
 => "6 E Bowen AVE Bensalem, PA 19020-1642" 

或者

match = str.match(REGEX)
match[1]
=> "6 E Bowen AVE Bensalem, PA 19020-1642"

为什么812的前三位数字丢失了?

1
如果地址是 str = "fdsfd 2-8126 E Bowen..." 呢?请注意,你的正则表达式结尾的 .+/./ 是相同的(也和 .+$/ 相同)。此外,如果你的正则表达式只包含了几个州的缩写(比如说4个),那么这并不会改变问题,读者也不需要横向滚动来阅读它。 - Cary Swoveland
1个回答

7
以下正则表达式已经可以正常工作,您可以在Regex101中查看结果。
REGEX = /^.+?(\d+.+(?=AL|AK|AS|AZ|AR|CA|CO|CT|DE|DC|FM|FL|GA|GU|HI|ID|IL|IN|IA|KS|KY|LA|ME|MH|MD|MA|MI|MN|MS|MO|MT|NE|NV|NH|NJ|NM|NY|NC|ND|MP|OH|OK|OR|PW|PA|PR|RI|SC|SD|TN|TX|UT|VT|VI|VA|WA|WV|WI|WY)[A-Z]{2}[, ]+\d{5}(?:-\d{4})?).+/

请注意正则表达式开头附加了问号。
/^.+?(\d+...
    ^ 

默认情况下,您的第一个.+是贪婪的,它会消耗所有可能的数字,并且仍然允许正则表达式通过。通过在加号后面添加?,您可以使其变得懒惰而不是贪婪。

另一种选择是不捕获数字,就像这样:

/^[^\d]+(\d+...

[^\d]+将捕获除数字外的所有内容。


2
或者,使用\D代替[^\d]... 同样,\S\H\W等,请参见https://ruby-doc.org/core-2.5.0/Regexp.html#class-Regexp-label-Character+Classes - Sundeep
如果你缩短正则表达式,使用字符类来匹配州名缩写的第二个字母,就可以大大减少匹配字符串所需的步骤如此处所示 - ctwheels

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接