让我们看一下您对糟糕的正则表达式引擎所做的事情:
(?<street_name>[\w\D\. ]+)\s+
问题出在字符类内部:[\w\D\. ]+
. 以下定义来自 Ruby 的Regexp 类文档:
/\w/
- 一个单词字符([a-zA-Z0-9_])
/\D/
- 非数字字符([^0-9])
你告诉引擎选择:
abcdefghijklmnopqrstuvwxyz
ABCDEFGHIJKLMNOPQRSTUVWXYZ
0123456789
_
- 每个不是的字符
0123456789
.
和空格
换句话说,每一个可能的字符。你也可以使用:
(?<street_name>.+)
因为那会非常贪婪。这个 Rubular 示例显示您的模式允许引擎捕获抛出的所有内容,包括几乎整个字符串Storgata 38H, 0273 Oslo
:http ://rubular.com/r/nMfcB0cUdu
此外,\.
inside[]
是一样的,[.]
因为将句点作为通配符的特殊使用会在括号内自动转义。您不需要再次转义它来尝试使其文字化,因为它已经是文字化的。
我强烈建议使用 Rubular 来查看正则表达式的每个部分,并尝试与其他几个可能的地址字符串进行匹配,看看 Rubular 是否说这些模式会符合您的期望。完成后,尝试将完整的模式放在一起。照原样,我认为您的小节正在相互作用并掩盖了一些问题,这些问题稍后会再次困扰您。
我希望 [\w\D] 会选择除数字以外的所有单词字符......有什么办法吗?
啊。让我们再次深入研究文档:
POSIX 括号表达式也类似于字符类。它们为上述内容提供了一种可移植的替代方案,另外还有一个好处是它们包含非 ASCII 字符。例如,/\d/ 仅匹配 ASCII 十进制数字 (0-9);而 /[[:digit:]]/ 匹配 Unicode Nd 类别中的任何字符。
/[[:alnum:]]/ - 字母和数字字符
/[[:alpha:]]/ - 字母字符
/[[:blank:]]/ - 空格或制表符
/[[:cntrl:]]/ - 控制字符
/[[:digit:]]/ - 数字
/[[:graph:]]/ - 非空白字符(不包括空格、控制字符和类似字符)
/[[:lower:]]/ - 小写字母字符
/[[:print:]]/ - 与 [:graph:] 类似,但包含空格字符
/[[:punct:]]/ - 标点符号
/[[:space:]]/ - 空白字符([:blank:]、换行符、回车符等)
/[[:upper:]]/ - 大写字母
/[[:xdigit:]]/ - 十六进制数中允许的数字(即 0-9a-fA-F)
您想使用该/[[:alpha:]]/
模式。如图所示,它只会捕获一个字符,但它会在任何 POSIX 的“字母”字符集中,这是您想要的范围:
[4] (pry) main: 0> 'æ, ø and å'.scan(/[[:alpha:]]/)
[
[0] "æ",
[1] "直径",
[2] “一”,
[3] "n",
[4] "d",
[5] “奥”
]
这是一个小调整:
[5] (pry) main: 0> 'æ, ø and å'.scan(/[[:alpha:]]+/)
[
[0] "æ",
[1] "直径",
[2和”,
[3] “奥”
]