$re = '/^[ ]{0,3} # Leading space up to 3
(?<link_all>
(?<!\\\\)\[ # ID within brackets
(?!\^) # Make sure, this is not confused with a footnote
(?<link_id>.+?)
(?<!\\\\)\]
[ \t]* # Possibly with some space before colon
\:
[ \t]*\n?[ \t]* # Possibly with some space after the colon, possibly with a new line in between?
(?:
<(?<link_url>[^\>]+)> # link within <>
|
(?<link_url>\S+) # or link without <>
)
(?:
(?:
[ \t]+ # Either some space or tabs
|
[ \t]*\n[ \t]* # or a new line surrounded by 0 or more spaces or tabs
)
(?:
(?:
(?<link_title_container>[\'"]) # Title is surrounded ether by double or single quotes
(?<link_title>.+?)
\g{link_title_container} # make the sure enclosing mark balance
)
| # or
\((?<link_title>[^\)]+)\) # by parenthesis
)
)?
[ \t]*
(?<!\\\\)
\{
[[:blank:]\h]*
(?<link_attr>.+?)
[[:blank:]\h]*
\}
[ \t]* # Possibly ending with some trailing spaces or tab
)
(?:\n+|\Z) # terminated by a new line or end of file/mxJ';
$str = '[refid]: /path/to/something (Title) { .class #ref data-key=val }
Should not match:
[^block]:
Paragraph.
* List item
> Blockquote
Code block
';
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