regex和ruby的新手正在寻找一种方法来匹配任何以特定tld结尾的域名
我有以下电子邮件:
jane.doe@navy.mil
barak.obama@whitehouse.gov
john.doe@usa.army.mil
family@example.com
我正在尝试编写一个正则表达式,它将匹配任何具有顶级域.mil和.gov的电子邮件,但不会编写其余的。我尝试了以下内容:
/(..).mil/
但我不知道如何让它在.mil
我正在使用红宝石。这是我在rubular中尝试的内容: http://rubular.com/r/BP7tqgAntY
答案 0 :(得分:3)
认为你的意思是,
ADStructure
|
+-- ServiceData
|
+-- Eddystone
|
+-- EddystoneUID
+-- EddystoneURL
+-- EddystoneTLM
在红宝石中,
^(.*)\.(?:gov|mil)$
答案 1 :(得分:1)
我会使用类似的东西:
REGEX = /\.(?:mil|gov)$/
%w[
jane.doe@navy.mil
barak.obama@whitehouse.gov
john.doe@usa.army.mil
family@example.com
].each do |addr|
puts '"%s" %s' % [addr, (addr[REGEX] ? 'matches' : "doesn't match")]
end
# >> "jane.doe@navy.mil" matches
# >> "barak.obama@whitehouse.gov" matches
# >> "john.doe@usa.army.mil" matches
# >> "family@example.com" doesn't match
如果你知道你想要的TLD总是在字符串的末尾,那么一个匹配的简单模式就可以了。
这是有效的,因为addr[REGEX]
使用String's []
method将模式应用于字符串并返回匹配或nil:
'foo'[/oo/] # => "oo"
'bar'[/oo/] # => nil
如果您想在TLD之前捕获所有内容:
REGEX = /(.+)\.(?:mil|gov)$/
%w[
jane.doe@navy.mil
barak.obama@whitehouse.gov
john.doe@usa.army.mil
family@example.com
].map do |addr|
puts addr[REGEX, 1]
end
# >> jane.doe@navy
# >> barak.obama@whitehouse
# >> john.doe@usa.army
# >>
以更具“生产价值”的风格使用它:
SELECT_PATTERN = '\.(?:mil|gov)$' # => "\\.(?:mil|gov)$"
CAPTURE_PATTERN = "(.+)#{ SELECT_PATTERN }" # => "(.+)\\.(?:mil|gov)$"
SELECT_REGEX, CAPTURE_REGEX = [SELECT_PATTERN, CAPTURE_PATTERN].map{ |s|
Regexp.new(s)
}
SELECT_REGEX # => /\.(?:mil|gov)$/
CAPTURE_REGEX # => /(.+)\.(?:mil|gov)$/
addrs = %w[
jane.doe@navy.mil
barak.obama@whitehouse.gov
john.doe@usa.army.mil
family@example.com
].select{ |addr|
addr[SELECT_REGEX]
}.map { |addr|
addr[CAPTURE_REGEX, 1]
}
puts addrs
# >> jane.doe@navy
# >> barak.obama@whitehouse
# >> john.doe@usa.army
同样,你可以在没有正则表达式的情况下完成:
TLDs = %w[.mil .gov]
%w[
jane.doe@navy.mil
barak.obama@whitehouse.gov
john.doe@usa.army.mil
family@example.com
].each do |addr|
puts '"%s" %s' % [ addr, TLDs.any?{ |tld| addr.end_with?(tld) } ]
end
# >> "jane.doe@navy.mil" true
# >> "barak.obama@whitehouse.gov" true
# >> "john.doe@usa.army.mil" true
# >> "family@example.com" false
和
TLDs = %w[.mil .gov]
addrs = %w[
jane.doe@navy.mil
barak.obama@whitehouse.gov
john.doe@usa.army.mil
family@example.com
].select{ |addr|
TLDs.any?{ |tld| addr.end_with?(tld) }
}.map { |addr|
addr.split('.')[0..-2].join('.')
}
puts addrs
# >> jane.doe@navy
# >> barak.obama@whitehouse
# >> john.doe@usa.army
end_with?
返回true / false,无论字符串是否以该子字符串结尾,这比使用等效的正则表达式更快。 any?
查看数组以查找任何匹配条件并返回true / false。
如果要查看很长的TLD列表,使用编写良好的正则表达式可能会非常快,可能比使用any?
更快。这一切都取决于您的数据和要检查的TLD数量,因此您需要根据数据样本运行基准测试,以了解要走哪条路。