簡體   English   中英

即使轉義了特殊字符,正則表達式也不會返回任何結果

[英]Regex returns no results even after escaping special characters

我的正則表達式沒有返回匹配,即使該模式似乎與字符串匹配:

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

我期望結果為0,所以我可以使用$ 1,$ 2,$ 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來對此進行更正,該替代會首先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

下一個問題是嘗試將“ Park City”與\\w匹配。

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

\\w是字母和數字,僅\\w下划線,不能有空格。 您將需要[\\w\\s]+

現在,該“地址”適用於該特定地址,但它非常脆弱,並且可能會在許多其他地址上失敗。


但是在$1使用address =~ regex並不是在Ruby中進行匹配的最佳方法。 而是使用regex.match(address)返回一個MatchData對象。 然后,您可以將其用作數組。 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對象作為一個單元傳遞。

另一個快速的替代正則表達式:

regex = /(.+)\\n([^,]+),\s(\w{2})\s(\d+)/

在這里,我們使用非字符類來獲取郊區

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM