텍스트 문자열의 전체 URL이 아닌 URL의 루트와 일치시키고 싶습니다. 주어진:
http://www.youtube.com/watch?v=ClkQA2Lb_iE
http://youtu.be/ClkQA2Lb_iE
http://www.example.com/12xy45
http://example.com/random
www.example.com
또는 2 개의 마지막 인스턴스를 example.com
도메인으로 해결하려고 합니다.
나는 정규 표현식이 느리다는 것을 들었고 이것이 페이지의 두 번째 정규 표현식이 될 것이므로 정규 표현식없이 할 수 있다면 알려주십시오.
이 솔루션의 JS / jQuery 버전을 찾고 있습니다.
답변
npm 패키지 psl (Public Suffix List)을 사용하는 것이 좋습니다 . “공개 접미사 목록”은 국가 코드 최상위 도메인뿐만 아니라 루트 도메인으로 간주 될 유니 코드 문자 (예 : www. 食 狮. 公司 .cn, bckobe)의 모든 유효한 도메인 접미사 및 규칙 목록입니다. .jp 등). 자세한 내용은 여기를 참조 하십시오 .
시험:
npm install --save psl
그런 다음 “extractHostname”구현으로 다음을 실행하십시오.
let psl = require('psl');
let url = 'http://www.youtube.com/watch?v=ClkQA2Lb_iE';
psl.get(extractHostname(url)); // returns youtube.com
npm 패키지를 사용할 수 없으므로 아래에서 extractHostname 만 테스트하십시오.
function extractHostname(url) {
var hostname;
//find & remove protocol (http, ftp, etc.) and get hostname
if (url.indexOf("//") > -1) {
hostname = url.split('/')[2];
}
else {
hostname = url.split('/')[0];
}
//find & remove port number
hostname = hostname.split(':')[0];
//find & remove "?"
hostname = hostname.split('?')[0];
return hostname;
}
//test the code
console.log("== Testing extractHostname: ==");
console.log(extractHostname("http://www.blog.classroom.me.uk/index.php"));
console.log(extractHostname("http://www.youtube.com/watch?v=ClkQA2Lb_iE"));
console.log(extractHostname("https://www.youtube.com/watch?v=ClkQA2Lb_iE"));
console.log(extractHostname("www.youtube.com/watch?v=ClkQA2Lb_iE"));
console.log(extractHostname("ftps://ftp.websitename.com/dir/file.txt"));
console.log(extractHostname("websitename.com:1234/dir/file.txt"));
console.log(extractHostname("ftps://websitename.com:1234/dir/file.txt"));
console.log(extractHostname("example.com?param=value"));
console.log(extractHostname("https://facebook.github.io/jest/"));
console.log(extractHostname("//youtube.com/watch?v=ClkQA2Lb_iE"));
console.log(extractHostname("http://localhost:4200/watch?v=ClkQA2Lb_iE"));
프로토콜이나 포트 번호가 있더라도 도메인을 추출 할 수 있습니다. 이것은 매우 단순화 된 비 정규식 솔루션이므로 그렇게 할 것이라고 생각합니다.
* 귀하의 제안에 대해 @Timmerz, @renoirb, @rineez, @BigDong, @ ra00l, @ILikeBeansTacos, @CharlesRobertson에게 감사드립니다! @ ross-allen, 버그를보고 해 주셔서 감사합니다!
답변
정규 표현식을 사용하지 않는 깔끔한 트릭 :
var tmp = document.createElement ('a');
; tmp.href = "http://www.example.com/12xy45";
// tmp.hostname will now contain 'www.example.com'
// tmp.host will now contain hostname and port 'www.example.com:80'
위와 같은 함수로 위를 감싸면 도메인 부분을 URI에서 빼내는 가장 좋은 방법이 있습니다.
function url_domain(data) {
var a = document.createElement('a');
a.href = data;
return a.hostname;
}
답변
문자열을 구문 분석 할 필요가 없으며 URL을 URL
생성자에 인수로 전달하면됩니다 .
var url = 'http://www.youtube.com/watch?v=ClkQA2Lb_iE';
var hostname = (new URL(url)).hostname;
assert(hostname === 'www.youtube.com');
답변
이 시도:
var matches = url.match(/^https?\:\/\/([^\/?#]+)(?:[\/?#]|$)/i);
var domain = matches && matches[1]; // domain will be null if no match is found
결과에서 포트를 제외하려면이 표현식을 대신 사용하십시오.
/^https?\:\/\/([^\/:?#]+)(?:[\/:?#]|$)/i
편집 : 특정 도메인이 일치하지 않도록하려면 부정적 예측을 사용하십시오.(?!youtube.com)
/^https?\:\/\/(?!(?:www\.)?(?:youtube\.com|youtu\.be))([^\/:?#]+)(?:[\/:?#]|$)/i
답변
포트 번호와 특수 문자를 사용할 수 있으므로 URL 구문 분석이 까다로울 수 있습니다. 따라서 parseUri 와 같은 것을 사용 하여이 작업 을 수행하는 것이 좋습니다 . 수백 개의 URL을 구문 분석하지 않으면 성능이 문제가 될 것입니다.
답변
2020 답변
이에 대한 추가 종속성이 필요하지 않습니다! 성능을 최적화해야하는지 여부에 따라 두 가지 좋은 솔루션이 있습니다.
URL.hostname
가독성을 위해 사용
바벨 시대에 가장 깨끗하고 쉬운 해결책은를 사용하는 것 URL.hostname
입니다.
const getHostname = (url) => {
// use URL constructor and return hostname
return new URL(url).hostname;
}
// tests
console.log(getHostname("/programming/8498592/extract-hostname-name-from-string/"));
console.log(getHostname("https://developer.mozilla.org/en-US/docs/Web/API/URL/hostname"));
URL.hostname
는 URL API의 일부이며 IE ( caniuse )를 제외한 모든 주요 브라우저에서 지원됩니다 . 레거시 브라우저를 지원해야하는 경우 URL 폴리 필을 사용하십시오 .
이 솔루션을 사용하면 다른 URL 속성 및 메소드에 액세스 할 수도 있습니다 . 예를 들어 URL의 경로 이름 또는 쿼리 문자열 params 도 추출하려는 경우에 유용합니다 .
성능을 위해 RegEx 사용
URL.hostname
앵커 솔루션 또는 parseUri를 사용하는 것보다 빠릅니다 . 그러나 여전히 gilly3의 정규 표현식 보다 훨씬 느립니다 .
const getHostnameFromRegex = (url) => {
// run against regex
const matches = url.match(/^https?\:\/\/([^\/?#]+)(?:[\/?#]|$)/i);
// extract hostname (will be null if no match is found)
return matches && matches[1];
}
// tests
console.log(getHostnameFromRegex("/programming/8498592/extract-hostname-name-from-string/"));
console.log(getHostnameFromRegex("https://developer.mozilla.org/en-US/docs/Web/API/URL/hostname"));
이 jsPerf에서 직접 테스트하십시오.
많은 수의 URL을 처리해야하는 경우 (성능이 중요한 경우)이 솔루션을 대신 사용하는 것이 좋습니다. 그렇지 않으면 URL.hostname
가독성을 선택하십시오 .
답변
나는 주어진 솔루션을 사용하려고 시도했는데, 선택된 솔루션은 내 목적을 위해 과잉이었고 “요소 만들기”는 나를 엉망으로 만듭니다.
아직 URL에 포트가 준비되지 않았습니다. 누군가가 유용하다고 생각하기를 바랍니다.
function parseURL(url){
parsed_url = {}
if ( url == null || url.length == 0 )
return parsed_url;
protocol_i = url.indexOf('://');
parsed_url.protocol = url.substr(0,protocol_i);
remaining_url = url.substr(protocol_i + 3, url.length);
domain_i = remaining_url.indexOf('/');
domain_i = domain_i == -1 ? remaining_url.length - 1 : domain_i;
parsed_url.domain = remaining_url.substr(0, domain_i);
parsed_url.path = domain_i == -1 || domain_i + 1 == remaining_url.length ? null : remaining_url.substr(domain_i + 1, remaining_url.length);
domain_parts = parsed_url.domain.split('.');
switch ( domain_parts.length ){
case 2:
parsed_url.subdomain = null;
parsed_url.host = domain_parts[0];
parsed_url.tld = domain_parts[1];
break;
case 3:
parsed_url.subdomain = domain_parts[0];
parsed_url.host = domain_parts[1];
parsed_url.tld = domain_parts[2];
break;
case 4:
parsed_url.subdomain = domain_parts[0];
parsed_url.host = domain_parts[1];
parsed_url.tld = domain_parts[2] + '.' + domain_parts[3];
break;
}
parsed_url.parent_domain = parsed_url.host + '.' + parsed_url.tld;
return parsed_url;
}
이것을 실행 :
parseURL('https://www.facebook.com/100003379429021_356001651189146');
결과:
Object {
domain : "www.facebook.com",
host : "facebook",
path : "100003379429021_356001651189146",
protocol : "https",
subdomain : "www",
tld : "com"
}