Python Domain Name Regular Expression Pattern
Question: I would like to be able to match a domain by following the below rules:

  * The domain name should be a-z | A-Z | 0-9 and hyphen(-)
  * The domain name should between 1 and 63 characters long
  * Last Tld must be at least two characters, and a maximum of 6 characters
  * The domain name should not start or end with hyphen (-) (e.g. -google.com or google-.com)
  * The domain name can be a subdomain (e.g. mkyong.blogspot.com)

I already have the java flavored regex I just need this python flavored

    
    
    ^((?!-)[A-Za-z0-9-]{1,63}(?<!-)\\.)+[A-Za-z]{2,6}$
    

I couldn't find any python regex for this matter as everyone expects the use
of urlparse. I don't need to split a url by domain, port, tlds and so on, I
only need to do a simple domain replace so regex should be the solution for me

What I have done:

    
    
    expectedstring = re.sub(r"^((?!-)[A-Za-z0-9-]{1,63}(?<!-)\\.)+[A-Za-z]{2,6}$" , "XXX" , string)
    

Example strings:

    
    
    string = "This is why this domain example.com will never be the same after some years, it might just be example.co.uk but will never get to example.-com. Documents could be located in this specific location http://en.example.com/documents/print.doc as you probably already know."
    
    expectedstring = "This is why this domain XXX will never be the same after some years, it might just be XXX but will never get to example.-com. Documents could be located in this specific location http://XXX/documents/print.doc as you probably already know."
    

List of valid domain names

  * www.google.com
  * google.com
  * mkyong123.com
  * mkyong-info.com
  * sub.mkyong.com
  * sub.mkyong-info.com
  * mkyong.com.au
  * g.co
  * mkyong.t.t.co

List of invalid domain names, and why.

  * mkyong.t.t.c - Tld must between 2 and 6 long
  * mkyong,com - Comma is not allow
  * mkyong - No Tld
  * mkyong.123 , Tld not allow digit
  * .com - Must start with [A-Za-z0-9]
  * mkyong.com/users - No Tld
  * mkyong.com - Cannot begin with a hyphen -
  * mkyong-.com - Cannot end with a hyphen -
  * sub.-mkyong.com - Cannot begin with a hyphen -
  * sub.mkyong-.com - Cannot end with a hyphen -


Answer: I run a test based on the list of given domain names (python 2.7x):

    
    
    import re
    valid_domains = """
    www.google.com
    google.com
    mkyong123.com
    mkyong-info.com
    sub.mkyong.com
    sub.mkyong-info.com
    mkyong.com.au
    g.co
    mkyong.t.t.co
    """
    
    invalid_domains = """
    mkyong.t.t.c
    mkyong,com
    mkyong
    mkyong.123
    .com
    mkyong.com/users
    -mkyong.com
    mkyong-.com
    sub.-mkyong.com
    sub.mkyong-.com
    """
    
    valid_names = valid_domains.split()
    invalid_names = invalid_domains.split()
    
    # match 1 character domain name or 2+ domain name
    pattern = '^([A-Za-z0-9]\.|[A-Za-z0-9][A-Za-z0-9-]{0,61}[A-Za-z0-9]\.){1,3}[A-Za-z]{2,6}$'
    
    print 'checking valid domain names ============'
    for name in valid_names:
        print name.ljust(50), ('True' if re.match(pattern, name) else 'False').rjust(5)
    
    print '\nchecking invalid domain names ============'
    for name in invalid_names:
        print name.ljust(50), ('True' if re.match(pattern, name) else 'False').rjust(5)
    

Output:

    
    
    checking valid domain names ============
    www.google.com                                      True
    google.com                                          True
    mkyong123.com                                       True
    mkyong-info.com                                     True
    sub.mkyong.com                                      True
    sub.mkyong-info.com                                 True
    mkyong.com.au                                       True
    g.co                                                True
    mkyong.t.t.co                                       True
    
    checking invalid domain names ============
    mkyong.t.t.c                                       False
    mkyong,com                                         False
    mkyong                                             False
    mkyong.123                                         False
    .com                                               False
    mkyong.com/users                                   False
    -mkyong.com                                        False
    mkyong-.com                                        False
    sub.-mkyong.com                                    False
    sub.mkyong-.com                                    False
    

[Edit] To achieve the same result as the expectedstring provided, I come up
with the following approach (without checking "http(s)")：

    
    
    import re
    
    # match 1 character domain name or 2+ domain name
    pattern = '(//|\s+|^)(\w\.|\w[A-Za-z0-9-]{0,61}\w\.){1,3}[A-Za-z]{2,6}'
    
    string = "This is why this domain example.com will never be the same after some years, it might just be example.co.uk but will never get to example.-com. Documents could be located in this specific location http://en.example.com/documents/print.doc as you probably already know."
    expectedstring = "This is why this domain XXX will never be the same after some years, it might just be XXX but will never get to example.-com. Documents could be located in this specific location http://XXX/documents/print.doc as you probably already know."
    
    resultstring = ''.join([re.sub(pattern , "\g<1>XXX" , string)])
    
    print 'resultstring: \n', resultstring
    print '\nare they equal? ', expectedstring == resultstring
    

Output is:

    
    
    resultstring: 
    This is why this domain XXX will never be the same after some years, it might just be XXX but will never get to example.-com. Documents could be located in this specific location http://XXX/documents/print.doc as you probably already know.
    
    are they equal?  True
    

