Two questions, two patterns
"Match a URL" is actually two different questions:
- Is this whole string a URL? (validation)
- Find URLs in this text. (extraction)
Different patterns, different anchoring.
Validation pattern
^https?://[\w-]+(\.[\w-]+)+(/[\w./?%&=+#-]*)?$
Accepts http or https, requires a domain with at least one dot, optionally a path with allowed URL characters.
Extraction pattern
For finding URLs in free-form text, you want to be more permissive but stop at obvious word boundaries:
https?://[^\s)]+
Matches http(s):// followed by anything that's not whitespace or a closing paren. The closing-paren stop prevents URLs in markdown like (https://example.com) from including the trailing ).
The trailing punctuation problem
URLs at the end of sentences pick up trailing periods, commas, parens. Solution: use a negated class that excludes those, OR strip trailing punctuation in code after the match.
Don't try to fully validate URLs with regex
Real URL validation is messy: scheme variants, IP literals, port numbers, internationalized domains, fragment encoding. For "does this URL parse and resolve?", use your language's URL library: Python urllib.parse.urlparse, JavaScript new URL(...), Go net/url.