即使在转义特殊字符后,正则表达式也不会返回任何结果

时间:2017-03-15 22:50:41

标签: ruby regex

我的正则表达式没有返回匹配,即使模式看起来与字符串匹配:

regex = /(.+)\\\\n(\w+),\s(\w{2})\s(\d+)/
address = "6761 SW 19 St\\nPark City, PA 19020"
address =~ regex
 => nil 

我期待0的结果,所以我可以使用$ 1,$ 2,$ 3来提取我想要的数据。

我能想象的唯一错误就是转义序列。但我是否像上面那样逃脱了?

2 个答案:

答案 0 :(得分:3)

解析地址非常棘手,要么编写一个过于简单的正则表达式并不容易捕获所有许多特殊情况,或者陷入试图捕获的兔子洞中,这很容易所有这些特殊情况。

幸运的是,已经有两个非常完善的模块:GeocoderStreetAddress。我个人致力于改进StreetAddress。

StreetAddress只是尽可能地解析地址。

2.3.3 :001 > address = "6761 SW 19 St\\\nPark City, PA 19020"
 => "6761 SW 19 St\\\nPark City, PA 19020" 
2.3.3 :002 > require 'street_address'
 => true 
2.3.3 :005 > StreetAddress::US.parse(address)
 => #<StreetAddress::US::Address:0x007fcc62a88ca8 @number="6761", @street="19 St\\", @street_type="Park", @unit=nil, @unit_prefix=nil, @suffix=nil, @prefix="SW", @city="City", @state="PA", @postal_code="19020", @postal_code_ext=nil> 

请注意,它将反斜杠保留为街道名称的一部分。地址中的反斜杠非常不正常。您可以通过覆盖StreetAddress::US.parse进行更正,首先删除尾部反斜杠。

Geocoder采用不同的方法对美国人口普查数据进行模糊匹配。设置起来有点困难,但它可以更好地解析真实的街道地址。

使用其中一个,不要自己编写。我只会将您的代码中的问题作为练习进行检查。

存在多个问题,其中任何一个都会导致匹配失败。这不能通过抛出更多的反斜杠来解决,直到它碰巧工作。

首先是地址本身。

address = "6761 SW 19 St\\nPark City, PA 19020"
                        ^

\\n是一个字面反斜杠,后跟字母n。

> address = "6761 SW 19 St\\nPark City, PA 19020"
 => "6761 SW 19 St\\nPark City, PA 19020" 
> puts address
6761 SW 19 St\nPark City, PA 19020

我希望你的意思是\\\n,这是一个字面反斜杠,后跟字母n。

然后你的正则表达式有多个问题。首先,太多的反斜杠。

/(.+)\\\\n(\w+),\s(\w{2})\s(\d+)/
     ^^^^^

这是两个字面反斜杠,后跟字母n。您需要\\\n

下一个问题是试图匹配&#34; Park City,&#34;与\w

/(.+)\\\n(\w+),\s(\w{2})\s(\d+)/
         ^^^^^^

\w是字母和数字,仅限下划线,没有空格。您需要[\w\s]+代替。

现在&#34;工作&#34;对于那个特定的地址,但它很脆弱,很可能会失败。

但是将address =~ regex$1一起使用并不是在Ruby中进行匹配的最佳方法。相反,使用返回MatchData对象的regex.match(address)。然后,您可以将其用作数组。 match[0]是匹配的一切。 match[1]$1(即第一次捕获),依此类推。

2.3.3 :034 > match[0]
 => "6761 SW 19 St\\\nPark City, PA 19020" 
2.3.3 :035 > match[1]
 => "6761 SW 19 St" 
2.3.3 :036 > match[2]
 => "Park City" 
2.3.3 :037 > match[3]
 => "PA" 
2.3.3 :038 > match[4]
 => "19020" 

这可以避免使用可能被其他正则表达式覆盖的变量,并允许您将MatchData对象作为单个单元传递。

答案 1 :(得分:0)

另一个快速替代正则表达式:

var express = require('express')
var cookieParser = require('cookie-parser');
var cookieSession = require('cookie-session');

var app = express();
app.use(cookieParser());
app.use(cookieSession());

这里我们使用not character class来获取郊区