我正在编写一个过滤程序,它读取包含地址数据的CSV文件,并排除位于新月(cres),avenue(ave)或place(pl)中的行.
这是一些示例输入:
data = <<CSV
ID,Street address,Town,Valuation date,Value
1,1 Northburn RD,WANAKA,1/1/2015,280000
2,1 Mount Ida PL,WANAKA,1/1/2015,280000
3,1 Mount Linton AVE,WANAKA,1/1/2015,780000
4,1 Centre CRES,WANAKA,1/1/2015,295000
CSV
require 'csv'
elements = []
CSV.parse(data, headers: true, header_converters: :symbol) do |row|
elements << row.to_h
end
elements
#=> [
# {:id=>"1", :street_address=>"1 Northburn RD", :town=>"WANAKA", :valuation_date=>"1/1/2015", :value=>"280000"},
# {:id=>"2", :street_address=>"1 Mount Ida PL", :town=>"WANAKA", :valuation_date=>"1/1/2015", :value=>"280000"},
# {:id=>"3", :street_address=>"1 Mount Linton AVE", :town=>"WANAKA", :valuation_date=>"1/1/2015", :value=>"780000"},
# {:id=>"4", :street_address=>"1 Centre CRES", :town=>"WANAKA", :valuation_date=>"1/1/2015", :value=>"295000"}
# ]
Run Code Online (Sandbox Code Playgroud)
我可以使用简单的正则表达式来过滤三个中的一个,即/pl/,/cres/和/ave/,但我不能使用它们链接它们&&(当我将它们分成三个单独的"过滤器"时它们也不起作用)
elements.select { |e| e[:street_address].downcase! !~ /pl/ && e[:street_address].downcase! !~ /cres/ && e[:street_address].downcase! !~ /ave/ }
#=> [
# {:id=>"1", :street_address=>"1 northburn rd", :town=>"WANAKA", :valuation_date=>"1/1/2015", :value=>"280000"},
# {:id=>"3", :street_address=>"1 mount linton ave", :town=>"WANAKA", :valuation_date=>"1/1/2015", :value=>"780000"},
# {:id=>"4", :street_address=>"1 centre cres", :town=>"WANAKA", :valuation_date=>"1/1/2015", :value=>"295000"}
# ]
Run Code Online (Sandbox Code Playgroud)
这会按预期过滤条目#2,但不过滤#3和#4.
我缺少什么想法?
这是因为downcase!- 它改变了接收器,nil如果没有做出改变则返回.
str = 'FOO'
str.downcase! #=> "foo"
str.downcase! #=> nil
Run Code Online (Sandbox Code Playgroud)
因此,你的第二次比较变成了nil !~ /cres/永远true.
要修复代码,请使用downcase(不!):
elements[:streetAddress].downcase !~ /pl/
Run Code Online (Sandbox Code Playgroud)
或者i在正则表达式中添加一个以使其不区分大小写:
elements[:streetAddress] !~ /pl/i
Run Code Online (Sandbox Code Playgroud)
此外,您可以组合正则表达式并使用reject:
elements.reject { |e| e[:streetAddress] =~ /pl|cres|ave/i }
Run Code Online (Sandbox Code Playgroud)
要只匹配字符串结束用"PL","CRES"或"AVE",使用适当的锚,例如/(pl|cres|ave)$/i
| 归档时间: |
|
| 查看次数: |
34 次 |
| 最近记录: |