แยกชื่อโฮสต์จากสตริง


239

ฉันต้องการจับคู่เฉพาะรากของ URL ไม่ใช่ URL ทั้งหมดจากสตริงข้อความ ได้รับ:

http://www.youtube.com/watch?v=ClkQA2Lb_iE
http://youtu.be/ClkQA2Lb_iE
http://www.example.com/12xy45
http://example.com/random

ฉันต้องการรับอินสแตนซ์สุดท้าย 2 รายการที่แก้ไขเป็นwww.example.comหรือexample.comโดเมน

ฉันได้ยินว่า regex ช้าและนี่จะเป็นนิพจน์ regex ที่สองของฉันบนหน้าดังนั้นหากมีอยู่แล้วที่จะทำโดยไม่ต้อง regex แจ้งให้เราทราบ

ฉันกำลังค้นหาโซลูชัน JS / jQuery เวอร์ชันนี้

คำตอบ:


281

ผมขอแนะนำให้ใช้ชุด NPM PSL (มหาชนคำต่อท้ายรายการ) "Public Suffix List" คือรายการของส่วนต่อท้ายโดเมนและกฎที่ถูกต้องทั้งหมดไม่เพียง แต่โดเมนระดับบนสุดของรหัสประเทศเท่านั้น .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"));

ไม่ว่าจะมีโพรโทคอลหรือแม้กระทั่งหมายเลขพอร์ตคุณสามารถแยกโดเมนได้ นี่เป็นวิธีที่ง่ายและไม่ regex ดังนั้นฉันคิดว่ามันจะทำ

* ขอบคุณ @Timmerz, @renoirb, @rineez, @BigDong, @ ra00l, @ILikeBeansTacos, @CharlesRobertson สำหรับคำแนะนำของคุณ! @ ross-allen ขอขอบคุณที่รายงานข้อผิดพลาด!


3
มันอาจจะดีกว่าที่จะสนับสนุนความยาวสัญกรณ์โปรโตคอลใด ๆ การปรับปรุงอาจจะมีurl.split('/')[2]ตั้งแต่ไม่คำนึงถึงเราเขียนftp, ftps, httpsชื่อโดเมนจะเป็นที่ดัชนี 2.
renoirb

1
ขึ้นอยู่กับสถานการณ์ของคุณคุณอาจต้องใช้return url.split('/')[2] || url.split('/')[0];สิ่งที่ตรงกันหากไม่มีโปรโตคอล
Timmerz

1
ทำไมคุณถึงเพิกเฉยต่อความจริงที่ว่าฟังก์ชั่นนี้จะไม่สามารถคืนชื่อโดเมนสำหรับอินพุตบางอย่างเช่น "ftp.websitename.com/dir/file.txt"
rineez

1
@renoirb ขออภัยฉันแล้วนี่จะติดตามการพิมพ์เป็ดได้อย่างไร
rineez

6
หนึ่งใน: youtube.com/watch -> www.youtube.com เป็นโดเมนย่อย www ของโดเมน youtube.com ในการลบ www พิเศษออกไปฉันได้เพิ่ม:if (domain.split('.').length > 2) { //has also subdomain var splitArr = domain.split('.'); domain = splitArr[splitArr.length - 2] + '.' + splitArr[splitArr.length - 1]; }
ra00l

306

เคล็ดลับเรียบร้อยโดยไม่ใช้นิพจน์ทั่วไป:

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;
}

8
ที่จริงฉันจะลองใช้วิธีแก้ปัญหา parseUri แต่ +1 ความคิดสร้างสรรค์
Chamilyan

11
@Chamilyan ฉันคิดว่าคุณควรจะยอมรับคำตอบนี้ .. มันเย็นมากและทำงานได้โดยไม่มีอะไรพิเศษ :)
Lipis

3
เพียงแค่ fyi - วิธีนี้ไม่ได้จัดการหมายเลขพอร์ต
Kyle

1
@ ไคล์มันแน่ใจว่าถ้าคุณหมายถึงหมายเลขพอร์ตควรเป็นส่วนหนึ่งของhostnameมันก็ไม่ควรถ้าคุณต้องการเข้าถึงทั้งสองhostnameและport(และได้รับมันเป็นdomain.sample:1234เพียงการเข้าถึงa.host)
Filip Roséen - refp

46
อย่าใช้วิธีนี้ถ้าคุณต้องการที่จะทำมันได้อย่างรวดเร็ว มันช้ากว่าวิธีของ gilly3 ประมาณ 40-60 เท่า การทดสอบใน jsperf: jsperf.com/hostname-from-url
cprcrack

138

ไม่จำเป็นต้องแยกสตริงเพียงแค่ส่ง URL ของคุณเป็นอาร์กิวเมนต์ให้กับตัวURLสร้าง :

var url = 'http://www.youtube.com/watch?v=ClkQA2Lb_iE';
var hostname = (new URL(url)).hostname;

assert(hostname === 'www.youtube.com');

6
เหมือนกับคำตอบโดย @mc ด้านล่าง ลองดูความคิดเห็นที่ "URL ใหม่ () ไม่ทำงานกับ IE (ทดสอบ IE11)"
Chamilyan

2
อาจเป็นวิธีที่ง่ายที่สุดในการทำงานกับวิธีแก้ปัญหาดังนั้น +1
Chamilyan

1
ฉันใช้สิ่งนี้ในส่วนขยายของ Chrome ดังนั้นจึงไม่มีการสนับสนุน IE ที่ใช้ได้กับฉันในขณะนี้
bodine

1
+1 นี่คือคำตอบที่ได้รับการยอมรับ มันรวดเร็วเชื่อถือได้และทำงานได้ในเบราว์เซอร์ที่ทันสมัยทั้งหมดไม่ได้ขึ้นอยู่กับไลบรารีภายนอกและง่ายต่อการเข้าใจ (ตรงข้ามกับโซลูชันของ regex) ฉันคิดว่ามันเร็วมากเพราะเป็นหัวใจของสิ่งที่เบราว์เซอร์ทุกตัวทำ (ไม่ใช่ว่ามันมักจะสำคัญมาก)
johndodo

128

ลองสิ่งนี้:

var matches = url.match(/^https?\:\/\/([^\/?#]+)(?:[\/?#]|$)/i);
var domain = matches && matches[1];  // domain will be null if no match is found

หากคุณต้องการแยกพอร์ตออกจากผลลัพธ์ให้ใช้นิพจน์นี้แทน:

/^https?\:\/\/([^\/:?#]+)(?:[\/:?#]|$)/i

แก้ไข:เพื่อป้องกันการจับคู่โดเมนที่เฉพาะเจาะจงใช้ lookahead เชิงลบ(?!youtube.com)

/^https?\:\/\/(?!(?:www\.)?(?:youtube\.com|youtu\.be))([^\/:?#]+)(?:[\/:?#]|$)/i

3
อย่าลืมรูปแบบเช่นโพรโทคอล: // ชื่อผู้ใช้: รหัสผ่าน @ โฮสต์: พอร์ต / พา ธ / ไปยัง / ทรัพยากร ...
Andrew White

1
ปิด แต่ URL อาจไม่มีเส้นทางและส่วนโฮสต์สามารถลงท้ายด้วย?' (query) or # `(แฟรกเมนต์) เช่นหรือhttp://example.com?var=val http://example.com#fragmentดังนั้น regex ที่ถูกต้องควรเป็นดังนี้: /^https?\:\/\/([^\/?#]+)/. นอกเหนือจากนั้นคุณจะได้รับ +1 ของฉัน (นี่เป็นวิธีแก้ปัญหาที่เร็วที่สุด)
ridgerunner

2
คุณอาจต้องการเพิ่มทางเลือก(?:www\.)?ในการมองเชิงลบ
ridgerunner

3
+1 เพราะมันเร็วมากซึ่งเป็นข้อกำหนดในกรณีของฉัน
cprcrack

8
@FellowStranger - เพิ่ม(?:www\.)?ไปยังนิพจน์ทั่วไปเช่นนี้:/^https?\:\/\/(?:www\.)?([^\/?#]+)(?:[\/?#]|$)/i
gilly3

36

การแยก URL อาจเป็นเรื่องยากเพราะคุณสามารถมีหมายเลขพอร์ตและตัวอักษรพิเศษ ดังนั้นฉันขอแนะนำให้ใช้บางอย่างเช่นparseUriเพื่อทำสิ่งนี้ให้คุณ ฉันสงสัยว่าประสิทธิภาพจะเป็นปัญหาเว้นแต่คุณจะแยกวิเคราะห์ URL เป็นร้อย ๆ


12
อย่าใช้วิธีนี้ถ้าคุณต้องการที่จะทำมันได้อย่างรวดเร็ว สำหรับการรับชื่อโฮสต์มันช้ากว่าวิธีของ gilly3 ประมาณ 40-60 การทดสอบใน jsperf: jsperf.com/hostname-from-url
cprcrack

นี่คือ URL ที่อัปเดต (อีกอันไม่พบ 404): javascriptoo.com/application/html/js/franzenzenhofer/parseUri/ …
ub3rst4r

@ BigDong บางทีคุณสามารถใช้ lib ได้อย่างง่ายดาย? nodejs.org/api/…
mc

2
ขออภัย URL ไม่ได้รับการสนับสนุนใน IE10
advncd

1
URL()ยังไม่รองรับอย่างสมบูรณ์ ตรวจสอบ: caniuse.com/#feat=url
Kousha

34

2563 ตอบ

คุณไม่ต้องการการพึ่งพาเพิ่มเติมสำหรับสิ่งนี้! ขึ้นอยู่กับว่าคุณต้องการปรับให้เหมาะสมสำหรับประสิทธิภาพหรือไม่มีสองโซลูชันที่ดี:

ใช้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 polyfillหากคุณต้องการสนับสนุนเบราว์เซอร์รุ่นเก่า

ใช้วิธีนี้ยังจะช่วยให้คุณสามารถเข้าถึงอื่น ๆคุณสมบัติ URL และวิธีการ สิ่งนี้จะเป็นประโยชน์หากคุณต้องการแยก URLชื่อพา ธหรือสตริงแบบสอบถามด้วย


ใช้ RegEx เพื่อประสิทธิภาพ

URL.hostnameจะเร็วกว่าการใช้วิธีการแก้ปัญหาสมอหรือparseUri อย่างไรก็ตามมันยังช้ากว่าregex ของ 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สำหรับการอ่าน


15

ฉันพยายามใช้วิธีแก้ปัญหาที่ได้รับสิ่งที่ได้รับเลือกคือ overkill สำหรับจุดประสงค์ของฉันและ "การสร้างองค์ประกอบ" ที่ทำให้ฉันยุ่งเหยิง

ยังไม่พร้อมสำหรับพอร์ตใน 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"
}

1
ฉันมักจะพลาดคำตอบที่โหวตน้อย แต่คำตอบนี้ทำให้ฉันระมัดระวัง ใช้งานได้ดี! ขอบคุณ @BlackDivine
Devaroop

ขอบคุณที่สละเวลาชื่นชมความพยายามของฉัน @Devaroop
BlackDivine

15

หากคุณท้ายหน้านี้และคุณกำลังมองหา REGEX ที่ดีที่สุดของ URL ลองอันนี้:

^(?:https?:)?(?:\/\/)?([^\/\?]+)

https://regex101.com/r/pX5dL9/1

มันใช้งานได้สำหรับ URL ที่ไม่มี http: //, กับ http, กับ https, ที่มีเพียง // และไม่ต้องคว้าพา ธ และพา ธ ของเคียวรีเช่นกัน

โชคดี


แม้ว่าลิงก์นี้อาจตอบคำถามได้ดีกว่าหากรวมส่วนสำคัญของคำตอบไว้ที่นี่และให้ลิงก์สำหรับการอ้างอิง คำตอบสำหรับลิงค์เท่านั้นอาจไม่ถูกต้องหากหน้าเว็บที่เชื่อมโยงมีการเปลี่ยนแปลง - จากรีวิว
Lawrence Aiello

1
แก้ไขและยื่น regex ไม่ :)
หลุยส์เปส

6

คุณสมบัติ URL ทั้งหมดไม่มีการพึ่งพาไม่มี JQuery เข้าใจง่าย

โซลูชันนี้ให้คำตอบของคุณพร้อมคุณสมบัติเพิ่มเติม ไม่ต้องใช้ JQuery หรือการอ้างอิงอื่น ๆ ให้วางและไป

การใช้

getUrlParts("https://news.google.com/news/headlines/technology.html?ned=us&hl=en")

เอาท์พุต

{
  "origin": "https://news.google.com",
  "domain": "news.google.com",
  "subdomain": "news",
  "domainroot": "google.com",
  "domainpath": "news.google.com/news/headlines",
  "tld": ".com",
  "path": "news/headlines/technology.html",
  "query": "ned=us&hl=en",
  "protocol": "https",
  "port": 443,
  "parts": [
    "news",
    "google",
    "com"
  ],
  "segments": [
    "news",
    "headlines",
    "technology.html"
  ],
  "params": [
    {
      "key": "ned",
      "val": "us"
    },
    {
      "key": "hl",
      "val": "en"
    }
  ]
}

รหัส
รหัสถูกออกแบบมาให้ง่ายต่อการเข้าใจมากกว่าเร็วมาก สามารถเรียกได้อย่างง่ายดาย 100 ครั้งต่อวินาทีดังนั้นจึงยอดเยี่ยมสำหรับส่วนหน้าหรือการใช้งานเซิร์ฟเวอร์เพียงเล็กน้อย แต่ไม่เหมาะสำหรับปริมาณงานที่มาก

function getUrlParts(fullyQualifiedUrl) {
    var url = {},
        tempProtocol
    var a = document.createElement('a')
    // if doesn't start with something like https:// it's not a url, but try to work around that
    if (fullyQualifiedUrl.indexOf('://') == -1) {
        tempProtocol = 'https://'
        a.href = tempProtocol + fullyQualifiedUrl
    } else
        a.href = fullyQualifiedUrl
    var parts = a.hostname.split('.')
    url.origin = tempProtocol ? "" : a.origin
    url.domain = a.hostname
    url.subdomain = parts[0]
    url.domainroot = ''
    url.domainpath = ''
    url.tld = '.' + parts[parts.length - 1]
    url.path = a.pathname.substring(1)
    url.query = a.search.substr(1)
    url.protocol = tempProtocol ? "" : a.protocol.substr(0, a.protocol.length - 1)
    url.port = tempProtocol ? "" : a.port ? a.port : a.protocol === 'http:' ? 80 : a.protocol === 'https:' ? 443 : a.port
    url.parts = parts
    url.segments = a.pathname === '/' ? [] : a.pathname.split('/').slice(1)
    url.params = url.query === '' ? [] : url.query.split('&')
    for (var j = 0; j < url.params.length; j++) {
        var param = url.params[j];
        var keyval = param.split('=')
        url.params[j] = {
            'key': keyval[0],
            'val': keyval[1]
        }
    }
    // domainroot
    if (parts.length > 2) {
        url.domainroot = parts[parts.length - 2] + '.' + parts[parts.length - 1];
        // check for country code top level domain
        if (parts[parts.length - 1].length == 2 && parts[parts.length - 1].length == 2)
            url.domainroot = parts[parts.length - 3] + '.' + url.domainroot;
    }
    // domainpath (domain+path without filenames) 
    if (url.segments.length > 0) {
        var lastSegment = url.segments[url.segments.length - 1]
        var endsWithFile = lastSegment.indexOf('.') != -1
        if (endsWithFile) {
            var fileSegment = url.path.indexOf(lastSegment)
            var pathNoFile = url.path.substr(0, fileSegment - 1)
            url.domainpath = url.domain
            if (pathNoFile)
                url.domainpath = url.domainpath + '/' + pathNoFile
        } else
            url.domainpath = url.domain + '/' + url.path
    } else
        url.domainpath = url.domain
    return url
}

ล้มเหลวในการแยกวิเคราะห์แบบง่าย ๆ ลองใช้getUrlParts('www.google.com')คอนโซลในหน้านี้
Chamilyan

@Camilyan นั่นไม่ใช่ url, url's มีโปรโตคอล อย่างไรก็ตามฉันได้อัปเดตรหัสเพื่อจัดการกรณีทั่วไปมากขึ้นดังนั้นโปรดนำ downvote ของคุณกลับมา
whitneyland

ฉันไม่ได้ลงคะแนนคุณ แต่ฉันจะได้รับถ้าฉันไม่ได้ขอเฉพาะ http: // ในคำถามดั้งเดิมของฉัน
Chamilyan

2
@Lee ล้มเหลวในการป้อนข้อมูลนี้: ควรจะเป็นแต่มันจะออกผลลัพธ์: ในขณะที่เป็นโดเมนย่อย (โดเมนสามารถมีโดเมนย่อยหลาย) var url="https://mail.gggg.google.cn/link/link/link";domainrootgoogle.comgggg.google.cngggg
ไม่มี


4

กำลังมองหาวิธีแก้ไขปัญหานี้ในวันนี้ ดูเหมือนว่าจะไม่มีคำตอบใด ๆ ที่กล่าวมาข้างต้น ฉันต้องการวิธีแก้ปัญหาที่อาจเป็นสายการบินเดียวไม่มีตรรกะตามเงื่อนไขและไม่มีสิ่งใดที่จะต้องห่อหุ้มด้วยฟังก์ชั่น

นี่คือสิ่งที่ฉันเกิดขึ้นดูเหมือนว่าจะทำงานได้ดีจริงๆ:

ชื่อโฮสต์ = "http://www.example.com:1234"
hostname.split ("//"). slice (-1) [0] .split (":") [0] .split ('.'). slice (-2) .join ('.') // ให้ "example.com"

อาจดูซับซ้อนในแวบแรก แต่ก็ใช้งานได้ง่าย กุญแจคือการใช้ 'slice (-n)' ในสองสถานที่ที่จะต้องดึงส่วนที่ดีออกจากจุดสิ้นสุดของอาร์เรย์ที่แยก (และ [0] เพื่อรับจากด้านหน้าของอาร์เรย์ที่แยก)

การทดสอบเหล่านี้แต่ละครั้งจะส่งคืน "example.com":

"http://example.com" .split ( "//") .slice (-1) [0] .split ( ":"). [0] .split ( '') ชิ้น (-2) เข้าร่วม ( '')
"http://example.com:1234".split("//").slice(-1)[0].split(":")[0].split('.').slice(-2 ) .join ( '')
"http://www.example.com:1234" .split ( "//") .slice (-1) [0] .split ( ":") [0] .split ( '') ชิ้น (. -2) .join ( '')
"http://foo.www.example.com:1234" .split ( "//") .slice (-1) [0] .split ( ":") [0] .split ( '') ชิ้น (-2) .join ( '')

ดีเพราะมันจัดการกับกรณีที่ www ไม่เกี่ยวข้อง
Chamilyan


3
String.prototype.trim = function(){return his.replace(/^\s+|\s+$/g,"");}
function getHost(url){
    if("undefined"==typeof(url)||null==url) return "";
    url = url.trim(); if(""==url) return "";
    var _host,_arr;
    if(-1<url.indexOf("://")){
        _arr = url.split('://');
        if(-1<_arr[0].indexOf("/")||-1<_arr[0].indexOf(".")||-1<_arr[0].indexOf("\?")||-1<_arr[0].indexOf("\&")){
            _arr[0] = _arr[0].trim();
            if(0==_arr[0].indexOf("//")) _host = _arr[0].split("//")[1].split("/")[0].trim().split("\?")[0].split("\&")[0];
            else return "";
        }
        else{
            _arr[1] = _arr[1].trim();
            _host = _arr[1].split("/")[0].trim().split("\?")[0].split("\&")[0];
        }
    }
    else{
        if(0==url.indexOf("//")) _host = url.split("//")[1].split("/")[0].trim().split("\?")[0].split("\&")[0];
        else return "";
    }
    return _host;
}
function getHostname(url){
    if("undefined"==typeof(url)||null==url) return "";
    url = url.trim(); if(""==url) return "";
    return getHost(url).split(':')[0];
}
function getDomain(url){
    if("undefined"==typeof(url)||null==url) return "";
    url = url.trim(); if(""==url) return "";
    return getHostname(url).replace(/([a-zA-Z0-9]+.)/,"");
}

ดังนั้นฉันเพิ่มความคิดเห็นที่นี่: รหัสที่ทำงานได้แม้จะมี url ซึ่งเริ่มต้นจาก // หรือมีข้อผิดพลาดทางไวยากรณ์เช่น qqq.qqq.qqq & test = 2 หรือมีพารามิเตอร์แบบสอบถามด้วย URL เช่น? param = www.www
QazyCat

3
function hostname(url) {
    var match = url.match(/:\/\/(www[0-9]?\.)?(.[^/:]+)/i);
    if ( match != null && match.length > 2 && typeof match[2] === 'string' && match[2].length > 0 ) return match[2];
}

โค้ดด้านบนจะวิเคราะห์ชื่อโฮสต์สำหรับ URL ตัวอย่างต่อไปนี้ได้สำเร็จ:

http://WWW.first.com/folder/page.html first.com

http://mail.google.com/folder/page.html mail.google.com

https://mail.google.com/folder/page.html mail.google.com

http://www2.somewhere.com/folder/page.html?q=1 ที่ไหนสักแห่งที่. com

https://www.another.eu/folder/page.html?q=1 another.eu

เครดิตดั้งเดิมไปที่: http://www.primaryobjects.com/CMS/Article145


3

โอเคฉันรู้ว่านี่เป็นคำถามเก่า แต่ฉันสร้างตัวแยกวิเคราะห์ URL ที่มีประสิทธิภาพมากขึ้นดังนั้นฉันคิดว่าฉันจะแชร์มัน

อย่างที่คุณเห็นโครงสร้างของฟังก์ชั่นนั้นแปลกมาก แต่ก็เพื่อประสิทธิภาพ ไม่มีการใช้ฟังก์ชันต้นแบบสตริงไม่ได้รับการทำซ้ำมากกว่าหนึ่งครั้งและไม่มีการประมวลผลอักขระเกินความจำเป็น

function getDomain(url) {
    var dom = "", v, step = 0;
    for(var i=0,l=url.length; i<l; i++) {
        v = url[i]; if(step == 0) {
            //First, skip 0 to 5 characters ending in ':' (ex: 'https://')
            if(i > 5) { i=-1; step=1; } else if(v == ':') { i+=2; step=1; }
        } else if(step == 1) {
            //Skip 0 or 4 characters 'www.'
            //(Note: Doesn't work with www.com, but that domain isn't claimed anyway.)
            if(v == 'w' && url[i+1] == 'w' && url[i+2] == 'w' && url[i+3] == '.') i+=4;
            dom+=url[i]; step=2;
        } else if(step == 2) {
            //Stop at subpages, queries, and hashes.
            if(v == '/' || v == '?' || v == '#') break; dom += v;
        }
    }
    return dom;
}

3

นี่ไม่ใช่คำตอบเต็มรูปแบบ แต่รหัสด้านล่างจะช่วยคุณ:

function myFunction() {
    var str = "https://www.123rf.com/photo_10965738_lots-oop.html";
    matches = str.split('/');
    return matches[2];
}

ฉันต้องการให้คนสร้างรหัสได้เร็วกว่าของฉัน มันช่วยปรับปรุงตัวฉันเองด้วย



2
// use this if you know you have a subdomain
// www.domain.com -> domain.com
function getDomain() {
  return window.location.hostname.replace(/([a-zA-Z0-9]+.)/,"");
}

2

ฉันเองค้นคว้ามากสำหรับวิธีนี้และสิ่งที่ดีที่สุดที่ฉันสามารถหาได้จาก "การตรวจสอบเบราว์เซอร์" ของ CloudFlare:

function getHostname(){  
            secretDiv = document.createElement('div');
            secretDiv.innerHTML = "<a href='/'>x</a>";
            secretDiv = secretDiv.firstChild.href;
            var HasHTTPS = secretDiv.match(/https?:\/\//)[0];
            secretDiv = secretDiv.substr(HasHTTPS.length);
            secretDiv = secretDiv.substr(0, secretDiv.length - 1);
            return(secretDiv);  
}  

getHostname();

ฉันเขียนตัวแปรใหม่เพื่อให้อ่านได้ง่ายกว่า "คน" แต่ทำงานได้ดีกว่าที่คาดไว้


2

การใช้นิพจน์ทั่วไปจะทำได้ง่ายขึ้นมาก:

    mainUrl = "http://www.mywebsite.com/mypath/to/folder";
    urlParts = /^(?:\w+\:\/\/)?([^\/]+)(.*)$/.exec(mainUrl);
    host = Fragment[1]; // www.mywebsite.com

2
import URL from 'url';

const pathname = URL.parse(url).path;
console.log(url.replace(pathname, ''));

สิ่งนี้จะดูแลทั้งโปรโตคอล


แน่นอนโมดูลนี้มีให้กับ NodeJS
djibe

1

ในระยะสั้นคุณสามารถทำเช่นนี้

var url = "http://www.someurl.com/support/feature"

function getDomain(url){
  domain=url.split("//")[1];
  return domain.split("/")[0];
}
eg:
  getDomain("http://www.example.com/page/1")

  output:
   "www.example.com"

ใช้ฟังก์ชั่นด้านบนเพื่อรับชื่อโดเมน


ปัญหาคืออะไร?
uzaif

ปัญหามันจะไม่ทำงานถ้าไม่มีสแลชมาก่อนหรือไม่
Toolkit

ในกรณีของคุณคุณต้องตรวจสอบ?ในสตริงชื่อโดเมนของคุณและแทนที่จะreturn domain.split("/")[0]; ทำให้return domain.split("?")[0];ความหวังนี้มันใช้งานได้
uzaif

1

0

รหัส:

var regex = /\w+.(com|co\.kr|be)/ig;
var urls = ['http://www.youtube.com/watch?v=ClkQA2Lb_iE',
            'http://youtu.be/ClkQA2Lb_iE',
            'http://www.example.com/12xy45',
            'http://example.com/random'];


$.each(urls, function(index, url) {
    var convertedUrl = url.match(regex);
    console.log(convertedUrl);
});

ผลลัพธ์:

youtube.com
youtu.be
example.com
example.com

@ChristianTernus ตรงกันข้าม; OP กล่าวถึง regex และนี่ค่อนข้างชัดเจนว่าเป็นนิพจน์ regex ที่ออกแบบมาให้ตรงกับส่วนที่ร้องขอของ URL มันไม่ได้เป็นทั้งหมดที่ถูกต้อง (เช่นมันต้องwww.แม้ว่า URL ที่ไม่ได้ทุกคนต้องมีส่วนนี้) แต่มันเป็นอย่างแน่นอนคำตอบ
Kyle Strand

@ KyleStrand พริตตี้ก็เห็นได้ชัดคือการตัดสินอัตนัย; การให้ regex แบบดิบเมื่อถูกถามว่า "ฉันกำลังมองหาโซลูชัน JS / jQuery เวอร์ชันนี้" ไม่ตอบคำถาม qeustion
คริสเตียนเทอร์นุส

ฉันเป็น OP ฉันเป็นนักพัฒนาใหม่ในขณะนั้นที่กำลังมองหาทางออกของกล่องใน JS แท้จริงแล้วสตริง regex ที่ไม่มีบริบทจะไม่ช่วยอะไรเลย บวกมันไม่สมบูรณ์
Chamilyan

0

แยกโดเมน - ห้องสมุดที่มีน้ำหนักเบามากที่เป็นของแข็ง

npm install parse-domain

const { fromUrl, parseDomain } = require("parse-domain");

ตัวอย่างที่ 1

parseDomain(fromUrl("http://www.example.com/12xy45"))
{ type: 'LISTED',
  hostname: 'www.example.com',
  labels: [ 'www', 'example', 'com' ],
  icann:
   { subDomains: [ 'www' ],
     domain: 'example',
     topLevelDomains: [ 'com' ] },
  subDomains: [ 'www' ],
  domain: 'example',
  topLevelDomains: [ 'com' ] }

ตัวอย่างที่ 2

parseDomain(fromUrl("http://subsub.sub.test.ExAmPlE.coM/12xy45"))
{ type: 'LISTED',
  hostname: 'subsub.sub.test.example.com',
  labels: [ 'subsub', 'sub', 'test', 'example', 'com' ],
  icann:
   { subDomains: [ 'subsub', 'sub', 'test' ],
     domain: 'example',
     topLevelDomains: [ 'com' ] },
  subDomains: [ 'subsub', 'sub', 'test' ],
  domain: 'example',
  topLevelDomains: [ 'com' ] }

ทำไม?

ขึ้นอยู่กับกรณีการใช้งานและปริมาณที่ฉันขอแนะนำอย่างยิ่งต่อการแก้ปัญหานี้ด้วยตัวคุณเองโดยใช้ regex หรือวิธีการจัดการสตริงอื่น ๆ หลักของปัญหานี้คือคุณจำเป็นต้องรู้ส่วนต่อท้าย gtld และ cctld ทั้งหมดเพื่อแยกวิเคราะห์สตริง url ในโดเมนและโดเมนย่อยอย่างถูกต้องส่วนต่อท้ายเหล่านี้จะได้รับการอัปเดตเป็นประจำ นี่เป็นปัญหาที่แก้ไขแล้วไม่ใช่สิ่งที่คุณต้องการแก้ปัญหาด้วยตัวคุณเอง (เว้นแต่คุณเป็น google หรือบางอย่าง) หากคุณไม่จำเป็นต้องใช้ชื่อโฮสต์หรือชื่อโดเมนในการบีบไม่ลองและแยกออกจากวิธีนี้


อาจเป็นปัญหาของสภาพแวดล้อม / เวอร์ชันลองดูที่npmjs.com/package/parse-domain
Glen Thompson

-1

รหัสของฉันมีลักษณะเช่นนี้ การแสดงออกปกติสามารถมาได้หลายรูปแบบและนี่คือกรณีทดสอบของฉันฉันคิดว่ามันสามารถปรับขนาดได้มากกว่า

function extractUrlInfo(url){
  let reg = /^((?<protocol>http[s]?):\/\/)?(?<host>((\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])|[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)))(\:(?<port>[0-9]|[1-9]\d|[1-9]\d{2}|[1-9]\d{3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5]))?$/
  return reg.exec(url).groups
}

var url = "https://192.168.1.1:1234"
console.log(extractUrlInfo(url))
var url = "/programming/8498592/extract-hostname-name-from-string"
console.log(extractUrlInfo(url))


-6

ลองรหัสด้านล่างสำหรับชื่อโดเมนที่แน่นอนโดยใช้ regex

String line = " http://www.youtube.com/watch?v=ClkQA2Lb_iE ";

  String pattern3="([\\w\\W]\\.)+(.*)?(\\.[\\w]+)";

  Pattern r = Pattern.compile(pattern3);


  Matcher m = r.matcher(line);
  if (m.find( )) {

    System.out.println("Found value: " + m.group(2) );
  } else {
     System.out.println("NO MATCH");
  }

2
OP ค้นหาคำตอบใน JavaScript ไม่ใช่ Java
piersadrian
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.