寻找一种方法来匹配以特定 tld 结尾的任何域电子邮件
Looking for a way to match any domain email ending with certain tld
正则表达式的新手,ruby 正在寻找一种方法来匹配任何以特定 tld 结尾的域
我有以下电子邮件:
jane.doe@navy.mil
barak.obama@whitehouse.gov
john.doe@usa.army.mil
family@example.com
我正在尝试编写一个正则表达式来匹配任何具有顶级域 .mil 和 .gov 的电子邮件,但不匹配其他域。我试过以下方法:
/(..).mil/
但我不知道如何让它匹配之前的所有内容.mil
我正在使用 ruby。这是我在 rubular 中尝试的内容:
http://rubular.com/r/BP7tqgAntY
我认为你是这个意思,
^(.*)\.(?:gov|mil)$
在ruby,
string.scan(/^.*(?=\.(?:gov|mil)$)/)
我会使用类似的东西:
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 将模式应用于字符串,returns 匹配或 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
# >>
以更 "production-worthy" 的方式使用它:
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?
returns a true/false whether the string ends with that substring, which is faster than using the equivalent regular expression. any?
遍历数组寻找任何匹配条件和 returns true/false.
如果您要检查一长串 TLD,使用编写良好的正则表达式会非常快,可能比使用 any?
更快。这完全取决于您的数据和要检查的 TLD 的数量,因此您需要 运行 对数据抽样进行基准测试以查看要走的路。
正则表达式的新手,ruby 正在寻找一种方法来匹配任何以特定 tld 结尾的域
我有以下电子邮件:
jane.doe@navy.mil
barak.obama@whitehouse.gov
john.doe@usa.army.mil
family@example.com
我正在尝试编写一个正则表达式来匹配任何具有顶级域 .mil 和 .gov 的电子邮件,但不匹配其他域。我试过以下方法:
/(..).mil/
但我不知道如何让它匹配之前的所有内容.mil
我正在使用 ruby。这是我在 rubular 中尝试的内容: http://rubular.com/r/BP7tqgAntY
我认为你是这个意思,
^(.*)\.(?:gov|mil)$
在ruby,
string.scan(/^.*(?=\.(?:gov|mil)$)/)
我会使用类似的东西:
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 将模式应用于字符串,returns 匹配或 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
# >>
以更 "production-worthy" 的方式使用它:
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?
returns a true/false whether the string ends with that substring, which is faster than using the equivalent regular expression. any?
遍历数组寻找任何匹配条件和 returns true/false.
如果您要检查一长串 TLD,使用编写良好的正则表达式会非常快,可能比使用 any?
更快。这完全取决于您的数据和要检查的 TLD 的数量,因此您需要 运行 对数据抽样进行基准测试以查看要走的路。