This program checks whether a string looks like a web address: http:// or https://, then a domain name with at least one dot, then an optional port and path.
The program
python
import re URL_PATTERN = re.compile(r"https?://([A-Za-z0-9-]+\.)+[A-Za-z]{2,}(:\d{1,5})?(/\S*)?") def is_valid_url(url): return URL_PATTERN.fullmatch(url) is not None tests = [ "https://www.example.com", "http://example.org/docs/page?id=7#top", "https://example.com:8080/api", "www.example.com", "ftp://example.com", "https://exa mple.com", "https://localhost:8000", ] for url in tests: print(f"{url:40} {is_valid_url(url)}")
output
https://www.example.com True http://example.org/docs/page?id=7#top True https://example.com:8080/api True www.example.com False ftp://example.com False https://exa mple.com False https://localhost:8000 False
How it works
https?://matcheshttp://orhttps://. The?makes thesoptional.([A-Za-z0-9-]+\.)+[A-Za-z]{2,}is the domain: one or more labels that end with a dot (www.,example.), then an ending of two or more letters (com).(:\d{1,5})?is an optional port, such as:8080.(/\S*)?is an optional path.\Smeans any character that is not a space, so the path can contain?,=and#.www.example.comfails because it has nohttp://orhttps://.https://localhost:8000fails becauselocalhosthas no dot. If you need to accept local addresses, change the domain part of the pattern.
Another way: urllib.parse
The standard library can split a URL into its parts. That is easier to read than a long regex, and you can then check each part:
python
from urllib.parse import urlparse parts = urlparse("https://example.com:8080/docs/page?id=7#top") print("scheme: ", parts.scheme) print("host: ", parts.hostname) print("port: ", parts.port) print("path: ", parts.path) print("query: ", parts.query) print("fragment:", parts.fragment) def is_web_url(url): parts = urlparse(url) return parts.scheme in ("http", "https") and bool(parts.hostname) and " " not in url print(is_web_url("https://www.example.com"), is_web_url("www.example.com"))
output
scheme: https host: example.com port: 8080 path: /docs/page query: id=7 fragment: top True False
urlparse() does not raise an error for a bad URL. It splits whatever you give it, so you still have to check that the parts you need are there.