我需要一个Java中的正则表达式,我可以用来从任何url中检索domain.tld部分。因此https://foo.com/bar,http://www.foo.com#bar,http://bar.foo.com都将返回foo.com。
我写了这个正则表达式,但它匹配整个网址
Pattern.compile("[.]?.*[.x][a-z]{2,3}");
我不确定我是否匹配“。”性格正确。我试过了 ”。”但是我从netbeans那里得到了一个错误。
更新
tld不限于2或3个字符,http://www.foo.co.uk/bar应返回foo.co.uk。
答案 0 :(得分:10)
这比你想象的要难。您的示例https://foo.com/bar中有一个逗号,它是一个有效的URL字符。这是一篇关于一些麻烦的好文章:
https://blog.codinghorror.com/the-problem-with-urls/
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 "<stdin>", line 1, in <module>
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需要一些无关的正则表达式的转义。
答案 1 :(得分:8)
我会使用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
答案 2 :(得分:7)
如果字符串包含有效的URL,那么您可以使用像(Perl引用)这样的正则表达式:
/^
(?:\w+:\/\/)?
[^:?#\/\s]*?
(
[^.\s]+
\.(?:[a-z]{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]+\\.(?:[a-z]{2,}|co\\.uk|org\\.uk|ac\\.uk|org\\.au|com\\.au|___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]+
\.(?:[a-z]{2,}|co\.uk|org\.uk|ac\.uk|org\.au|com\.au|___etc___)
)
(?:[:?#\/]|$)
/xi;
print "matched: $1\n";
}
答案 3 :(得分:4)
new URL(url).getHost()
不需要正则表达式。
答案 4 :(得分:3)
您需要获取所有可能的TLD和ccTLD的列表,然后与之匹配。你必须这样做,否则你永远无法区分subdomain.dom.com和hello.co.uk。
所以,让你自己这样一个清单。我建议将其反转,以便存储,例如,uk.co. 然后,您可以通过获取//和/或行尾之间的每个来从URL中提取域。分裂在。并向后工作,匹配TLD,然后再增加1个级别以获得域名。
答案 5 :(得分:0)
/[^.]*\.[^.]{2,3}(?:\.[^.]{2,3})?$/
几乎在那里,但是当二级域名有3个这样的字符时不会匹配: www.foo.com 测试here。
答案 6 :(得分:0)
这对我有用:
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;
}
答案 7 :(得分:0)
代码:
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