$re = '/^s*((https?:\/\/)((\S+\.+\S+)|(\[?(\S+:)+\S+\]?)|({.*}.*))?(?::\d+)?({.*}.*)?|({.*}.*))\s*$
/m';
$str = 'http://foo.bar
https://foo.bar
https://foo.bar/{foo}
{foo}
IPv4
http://foo123.bar/{Fave Country (South Africa):3.1}
https://foo123.bar/{field :1}
https://{field:1}
https://foo.bar/{field:1}/
https://foo.bar/{field:1}:8080?name=value#fragment
http://foo.bar
https://foo.bar/path/to/resource
http://192.168.0.1:8080/path/to/file/?name=value
https://[2001:db8::1]:443/resource
Starting with merge tag
{field:1}
{field:1}/path/to?name=value#fragment
IPv6
https://2001:0db8:85a3:0000:0000:8a2e:0370:7334
https://001:db8:85a3::8a2e:370:7334
https://::1
https://::ffff:192.0.2.128
https://[fe80::1%25eth0]/{field :1}
https://fe80::1%eth0
https://ff02::1
https://2001:4860:4860::8888
https://2001:db8::2:1
https://fd12:3456:789a:1::1
https://1234:5678:90ab:cdef::1
NON VALID:
htp://foo.bar
//foo.bar
dfdf{field:1}
http://foo
foo
https//foo
https://foodfdf
htp://foo.bar
foo.bar
http://foo
foo.bar/{field:1}
';
preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);
// Print the entire match result
var_dump($matches);
Please keep in mind that these code samples are automatically generated and are not guaranteed to work. If you find any syntax errors, feel free to submit a bug report. For a full regex reference for PHP, please visit: http://php.net/manual/en/ref.pcre.php