Find website URLs that begin with http:// or https:// This is a problem from Automate the Boring Stuff from "Pattern Matching with Regular Expression". I am a beginner in Python and the purpose of this program is to match urls which start with http:// or https://, with some urls having an optional www. after https://

How can this code be improved?

#! /usr/bin/python3
#websiteURL.py - Find website URLs that begin with http:// or https://

import pyperclip, re

#protocol Regex - checks for http:// or https://
protocolRegex = re.compile(r'''
    https?://           #match http:// or https://
    (?:w{3}\.)?         #www-dot
    [a-zA-Z0-9_-]+      #domin name
    \.                  #dot
    [a-zA-Z]{2,3}       #extension
    ''', re.VERBOSE)

text = str(pyperclip.paste()) #copying data from document to clipboard and converting it into a string
matches = [] #stores all matches in this list

for website in protocolRegex.findall(text): #finding website from the string text
    matches.append(website)

if len(matches) &gt; 0:
    pyperclip.copy('\n'.join(map(str, matches))) #copying result to clipboard after adding newline after each match
    print('Copied to clipboard:')
    print('\n'.join(matches))
else:
    print('No website found')


Running code:

chmod +x websiteURL.py
./websiteURL.py
Variable Names

Variables should be lower-cased and snake-case, meaning that multiple words should look like some_variable, not someVariable or SomeVariable. I think the name you've chosen for your regex is good and expresses exactly what it is:

protocol_regex = re.compile(...)


Checking length of a list/container data structure

It is not considered pythonic to check the emptiness of a container in python by using if len(container) == 0, most* containers have a __bool__ method built-in that allows you to do if not container for an empty one and if container for non-empty:

from collections import deque

if not {}:
    print("empty dict")
empty dict

if not []:
    print("empty list")
empty list

if not '':
    print("empty string")
empty string

if not deque():
    print("empty deque")
empty deque

if ['result1']:
    print('non-empty list')
non-empty list


One of the few that does not behave this way is queue.Queue, which I've included to give context to the most comment.

With this in mind, change your match check to:

if matches:
    # rest of code
else:
    # else code here