今天一天折騰了這麼一個正則git
new Regex(@"^!?\[((?:\[[^\]]*\]|[^\[\]]|\](?=[^\[]*\]))*)\]\s*\(\s*<?((?:[^()]|\((?<DEPTH>)|\)(?<-DEPTH>))+?(?(DEPTH)(?!)))>?(?:\s+(['""])([\s\S]*?)\3)?\s*\)");
話說這個正則是幹什麼用的,故事是這樣的:github
好久好久之前markdown
我在markdownlite裏面抄了個marked裏面的正則ui
一切都很好。spa
忽然,code
有用戶報咱們的markdown不對,blog
什麼狀況?get
一問是link的處理有問題。string
是什麼奇葩link那?it
打開一看,
映入眼簾的是:
[hello](foo(bar).md)
marked裏面的正則會處理成:
<a href="foo(bar">hello</a>bar).md)
確實bar後面都跟)了連接就處處爲止了,
看起來是用戶內容有問題啊!
再跑到github裏面一試,
傻眼了:
<a href="foo(bar).md">hello</a>
吐血中。。。
再試了不少case後,
發現github只要在link target裏面的的()是成對出現的就能work。
因而就有了今天這個正則。
這個複雜的正則須要這麼去理解:
^ start of string !? '!' 0~1 \[ '[' ((?:\[[^\]]*\]|[^\[\]]|\](?=[^\[]*\]))*) group 1: text \] ']' \s* white spaces \( '(' \s* white spaces <? '<' 0~1 ( start group 2: link (?: start non-capturing group [^()] any chararacter but '(' or ')' | or \((?<DEPTH>) '(' with depth++ | or \)(?<-DEPTH>) ')' with depth-- ) end non-capturing group +? lazy 1~ (?(DEPTH)(?!)) require depth = 0 ) end group 2: link >? '>' 0~1 (?: start non-capturing group \s+ white spaces (['"]) group 3: quote ' or " ([\s\S]*?) group 4: title \3 ref group 3 )? end non-capturing group 0~1 \s* white spaces \) ')'