用于检索domain.tld的正则表达式

我需要一个Java中的正则表达式,我可以用来从任何url中检索domain.tld部分。 所以https://foo.com/bar,http://www.foo.com#bar,http://bar.foo.com都将返回foo.com。

我写了这个正则表达式,但它匹配整个url

Pattern.compile("[.]?.*[.x][az]{2,3}"); 

我不确定我是否匹配“。” 性格正确。 我试过了 ”。” 但我从netbeans得到一个错误。

更新:

tld不限于2或3个字符, http://www.foo.co.uk/bar应返回foo.co.uk.

我将使用java.net.URI类来提取主机名,然后使用正则表达式来提取主机uri的最后两部分。

 import java.net.URI; import java.net.URISyntaxException; import java.util.regex.Matcher; import java.util.regex.Pattern; public class RunIt { public static void main(String[] args) throws URISyntaxException { Pattern p = Pattern.compile(".*?([^.]+\\.[^.]+)"); String[] urls = new String[] { "https://foo.com/bar", "http://www.foo.com#bar", "http://bar.foo.com" }; for (String url:urls) { URI uri = new URI(url); //eg: uri.getHost() will return "www.foo.com" Matcher m = p.matcher(uri.getHost()); if (m.matches()) { System.out.println(m.group(1)); } } } } 

打印:

 foo.com foo.com foo.com 

这比你想象的要难。 您的示例https://foo.com/bar中有一个逗号,这是一个有效的URL字符。 这是一篇关于一些麻烦的好文章:

http://www.codinghorror.com/blog/archives/001181.html

 https?://([-A-Za-z0-9+&@#/%?=~_()|!:,.;]*[-A-Za-z0-9+&@#/%=~_()|]) 

是一个很好的起点

关于此主题的“掌握正则表达式”中的一些列表:

http://regex.info/listing.cgi?ed=3&p=207

@sjobe

 >>> import re >>> pattern = r'https?://([-A-Za-z0-9+&@#/%?=~_()|!:,.;]*[-A-Za-z0-9+&@#/%=~_()|])' >>> url = re.compile(pattern) >>> url.match('http://news.google.com/').groups() ('news.google.com/',) >>> url.match('not a url').groups() Traceback (most recent call last): File "", line 1, in  AttributeError: 'NoneType' object has no attribute 'groups' >>> url.match('http://google.com/').groups() ('google.com/',) >>> url.match('http://google.com').groups() ('google.com',) 

对不起,这个例子是在python而不是java中,它更简短。 Java需要一些无关的正则表达式的逃避。

如果字符串包含有效的URL,那么您可以使用像(Perl引用)这样的正则表达式:

 /^ (?:\w+:\/\/)? [^:?#\/\s]*? ( [^.\s]+ \.(?:[az]{2,}|co\.uk|org\.uk|ac\.uk|org\.au|com\.au|___etc___) ) (?:[:?#\/]|$) /xi; 

结果:

 url: https://foo.com/bar matched: foo.com url: http://www.foo.com#bar matched: foo.com url: http://bar.foo.com matched: foo.com url: ftp://foo.com matched: foo.com url: ftp://www.foo.co.uk?bar matched: foo.co.uk url: ftp://www.foo.co.uk:8080/bar matched: foo.co.uk 

对于Java,它将被引用如下:

 "^(?:\\w+://)?[^:?#/\\s]*?([^.\\s]+\\.(?:[az]{2,}|co\\.uk|org\\.uk|ac\\.uk|org\\.au|com\\.au|___etc___))(?:[:?#/]|$)" 

当然你需要更换etc部分。

示例Perl脚本:

 use strict; my @test = qw( https://foo.com/bar http://www.foo.com#bar http://bar.foo.com ftp://foo.com ftp://www.foo.co.uk?bar ftp://www.foo.co.uk:8080/bar ); for(@test){ print "url: $_\n"; /^ (?:\w+:\/\/)? [^:?#\/\s]*? ( [^.\s]+ \.(?:[az]{2,}|co\.uk|org\.uk|ac\.uk|org\.au|com\.au|___etc___) ) (?:[:?#\/]|$) /xi; print "matched: $1\n"; } 

new URL(url).getHost()

不需要正则表达式。

您需要获取所有可能的TLD和ccTLD的列表,然后与它们进行匹配。 你必须这样做,否则你永远无法区分subdomain.dom.com和hello.co.uk。

所以,让你自己这样一个清单。 我建议将其反转,以便存储,例如,uk.co. 然后,您可以通过获取//和/或行尾之间的每个来从URL中提取域。 分裂在。 并向后工作,匹配TLD,然后再获得1个额外级别来获取域名。

  /[^.]*\.[^.]{2,3}(?:\.[^.]{2,3})?$/ 

几乎在那里,但是当二级域名有3个这样的字符时将无法匹配: http://www.foo.com 在这里测试它。

这对我有用:

 public static String getDomain(String url){ if(TextUtils.isEmpty(url)) return null; String domain = null; if(url.startsWith("http://")) { url = url.replace("http://", "").trim(); } else if(url.startsWith("https://")) { url = url.replace("https://", "").trim(); } String[] temp = url.split("/"); if(temp != null && temp.length > 0) { domain = temp[0]; } return domain; } 

码:

 public class DomainUrlUtils { private static String[] TLD = {"com", "net"}; // top-level domain private static String[] SLD = {"co\\.kr"}; // second-level domain public static String getDomainName(String url) { Pattern pattern = Pattern.compile("(?<=)[^(\\.|\\/)]\\w+\\.(" + joinTldAndSld("|") + ")$"); Matcher match = pattern.matcher(url); String domain = null; if (match.find()) { domain = match.group(); } return domain; } private static String joinTldAndSld(String delimiter) { String t = String.join(delimiter, TLD); String s = String.join(delimiter, SLD); return new StringBuilder(t).append(s.isEmpty() ? "" : "|" + s).toString(); } } 

测试:

 public class DomainUrlUtilsTest { @Test public void getDomainName() throws Exception { // given String[][] domainUrls = { { "test.com", "sub1.test.com", "sub1.sub2.test.com", "https://sub1.test.com", "http://sub1.sub2.test.com" }, { "https://domain.com", "https://sub.domain.com" }, { "http://domain.co.kr", "http://sub.domain.co.kr", "http://local.sub.domain.co.kr", "http://local-test.sub.domain.co.kr", "sub.domain.co.kr", "domain.co.kr", "test.sub.domain.co.kr" } }; String[] expectedUrls = { "test.com", "domain.com", "domain.co.kr" }; // when // then for (int domainIndex = 0; domainIndex < domainUrls.length; domainIndex++) { for (String url : domainUrls[domainIndex]) { String convertedUrl = DomainUrlUtils.getDomainName(url); if (expectedUrls[domainIndex].equals(convertedUrl)) { System.out.println(url + " -> " + convertedUrl); } else { Assert.fail("origin Url: " + url + " / converted Url: " + convertedUrl); } } } } } 

结果:

 test.com -> test.com sub1.test.com -> test.com sub1.sub2.test.com -> test.com https://sub1.test.com -> test.com http://sub1.sub2.test.com -> test.com https://domain.com -> domain.com https://sub.domain.com -> domain.com http://domain.co.kr -> domain.co.kr http://sub.domain.co.kr -> domain.co.kr http://local.sub.domain.co.kr -> domain.co.kr http://local-test.sub.domain.co.kr -> domain.co.kr sub.domain.co.kr -> domain.co.kr