sunilkumarba
sunilkumarba

Reputation: 891

Regular Expression - Extract subdomain & domain

I'm trying to form a regular expression (javascript/node.js) which will extract the sub-domain & domain part from any given URL. This is what I ended up with:

[^(?:http:\/\/|www\.|https:\/\/)]([^\/]+)

Right now, I'm just considering http, https for protocol & exclude "www." portion from the subdomain+domain portion of an URL. I checked the expression & it almost works. But, here is the issue:

Success

'http://mplay.google.co.in/sadfask/asdkfals?dk=10'.match(/[^(?:http:\/\/|www\.|https:\/\/)]([^\/]+)/i)

'http://lplay.google.co.in/sadfask/asdkfals?dk=10'.match(/[^(?:http:\/\/|www\.|https:\/\/)]([^\/]+)/i)

Failure

'http://play.google.co.in/sadfask/asdkfals?dk=10'.match(/[^(?:http:\/\/|www\.|https:\/\/)]([^\/]+)/i)

'http://tplay.google.co.in/sadfask/asdkfals?dk=10'.match(/[^(?:http:\/\/|www\.|https:\/\/)]([^\/]+)/i)

I just use the first element from the result array. I'm not able to understand why "play." & "tplay." doesn't work. Could anyone please help me in this regard?

Does "/p" and "/t" have any meaning for the regular expression evaluator?

Is there any other way of extracting sub-domain & domain from any given URL using a regular expression?

Edit -

Example:

https://play.google.com/store/apps/details?id=com.skgames.trafficracer => play.google.com

https://mail.google.com/mail/u/0/#inbox => mail.google.com

Upvotes: 42

Views: 157523

Answers (7)

anubhava
anubhava

Reputation: 785128

Your regex doesn't seem correct. Try this regex:

/^(?:https?:\/\/)?(?:[^@\n]+@)?(?:www\.)?([^:\/\n?]+)/img

Domain name will be available in capture group #1.

RegEx Demo

RegEx Details:

  • ^: Match start
  • (?:https?:\/\/)?: Match optional text https://
  • (?:[^@\n]+@)?: Match optional text : followed by 1+ of any text and @
  • (?:www\.)?: Match optional text www.
  • ([^:\/\n?]+): Match 1+ of any character that are not (line break and / and ? and :) and capture this value in capture group #1

Upvotes: 106

Wil
Wil

Reputation: 837

This JavaScript Regex using Named Capturing Groups breaks the link / URL up into its functional components:

console.log("https://www.sub.domain.google.com:443/maps/place/Arc+De+Triomphe/@48.8737917,2.2928388,17z?query=1&foo#hash".match(/^(?<protocol>https?:\/\/)(?=(?<fqdn>[^:/]+))(?:(?<service>www|ww\d|cdn|ftp|mail|pop\d?|ns\d?|git)\.)?(?:(?<subdomain>[^:/]+)\.)*(?<domain>[^:/]+\.[a-z0-9]+)(?::(?<port>\d+))?(?<path>\/[^?]*)?(?:\?(?<query>[^#]*))?(?:#(?<hash>.*))?/i).groups)

output:

{
  "protocol": "https://",
  "fqdn": "www.sub.domain.google.com",
  "service": "www",
  "subdomain": "sub.domain",
  "domain": "google.com",
  "port": "443",
  "path": "/maps/place/Arc+De+Triomphe/@48.8737917,2.2928388,17z",
  "query": "query=1&foo",
  "hash": "hash"
}

So you can use whatever components you like

Upvotes: 3

blueseal
blueseal

Reputation: 2908

I know I am late to the party but I want to answer the question with some extra useful info.

Get the domain name from a link using regex.

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

Here is the link to above regex.

If you want to get the subdomain, split the result from one of the matches of above regex with the first occurrence of .

Note: regex is faster than language built-in modules. check below examples, regex comes out to be 15x faster than the built-in module

javascript Example with Regex:

console.time('time2');
const pttrn = /^(https?:\/\/)?(www\.)?([^\/]+)/gm
const urlInfo = pttrn.exec("https://www.google.co.in/imghp");
console.timeEnd('time2');

//time2: 0.055ms
console.log(urlInfo[0]) // https://www.google.co.in
console.log(urlInfo[1]) // https://
console.log(urlInfo[2]) // www.
console.log(urlInfo[3]) // google.co.in

Nodejs with built-in url module

console.time('time');
const url = require('url');
const urlInfo = url.parse("https://www.google.co.in/imghp");
console.timeEnd('time');

//time: 0.840ms;
console.log(urlInfo.hostname) //www.google.co.in

Upvotes: 0

Nicu Surdu
Nicu Surdu

Reputation: 8301

The same RegExp as in anubhava's answer, only added support for protocol-relative URLs like //google.com:

/^(?:https?:)?(?:\/\/)?(?:[^@\n]+@)?(?:www\.)?([^:\/\n]+)/im

RegEx Demo

Upvotes: 11

user663031
user663031

Reputation:

You are about the one millionth person to try to parse URLs in JavaScript. I'm a little bit surprised you didn't see any of the existing questions on SO dating back years. The last thing you want to do is write yet another broken regexp, with all due respect to those that provided answers to your question.

There are many well documented libraries and approaches to handling this. Google it. The simplest way is to create an a element in memory, assign it an href, and then access its hostname and other properties. See http://tutorialzine.com/2013/07/quick-tip-parse-urls/. If that does not float your boat, then use a library like uri.js.

If you really don't want to use a library, and insist on reinventing the wheel, then at least do something like the following:

function get_domain_from_url(url) {
    var a = document.createElement('a').
    a.setAttribute('href', url);
    return a.hostname;
}

Essentially, you are delegating the extraction of the subdomain/domain part of the URL to the browser's URL parsing logic, which is MUCH better than anything you will ever write.

Also see Parse URL with jquery/ javascript?, Parse URL with Javascript, How do I parse a URL into hostname and path in javascript?, or parse URL with JavaScript or jQuery. How did you miss those? Sorry, I have to vote to close this as a duplicate.

Upvotes: 27

Academia
Academia

Reputation: 4124

Your regex expression works pretty well. You only need to remove the brackets. The final expression is:

^(?:http:\/\/|www\.|https:\/\/)([^\/]+)

Hope it's useful!

Upvotes: 3

Ashoka Lella
Ashoka Lella

Reputation: 6729

Here's a solution ignoring everything before ://

.*\://?([^\/]+)

Incase you want to ignore www.

.*\://(?:www.)?([^\/]+)

Upvotes: 10

Related Questions