用正则表达式捕获标识符——随便说
假設只接受public/private兩個修飾符,并且只接受void/bool/int三個返回類型,接受字段、屬性和函數。函數不允許有參數,屬性有get/set(為簡單起見,先get后set),字段只能是bool/int兩個類型(不允許初始化)。函數和屬性的內容為空,只有一對花括號。那是不是應該這么寫呢?
?
(?<function>(?<modifier>public|private)\s+(?<return_type>void|bool|int)\s+(?<function_name>\w+)\s*\(\s*\){\s*})|(?<property>(?<modifier>public|private)\s+(?<return_type>void|bool|int)\s+(?<property_name>\w+)\s*{\s*get\s*{\s*}\s*set\s*{\s*}\s*})|(?<variable>(?<modifier>public|private)\s+(?<variable_type>bool|int)\s+(?<variable_name>\w+)\s*;)
這么寫是對的,但是效率方面卻不是很好。對于這個簡單的情況可能還是體現不出來,但是如果更加復雜的話,可能就會出現效率低下的問題了。我們應該怎么怎么改呢?
(?<define>(?<modifier>public|private)\s+(?>(?<type>void)\s+(?<name>\w+)\s*(?>(?<function>\(\s*\)\s*{\s*})|(?<property>{\s*get\s*{\s*}\s*set\s*{\s*}\s*}))|(?<type>bool|int)\s+(?<name>\w+)\s*(?>(?<function>\(\s*\)\s*{\s*})|(?<property>{\s*get\s*{\s*}\s*set\s*{\s*}\s*})|(?<variable>;))))
這種寫法跟上面那一種寫法有什么不一樣呢?對于
public int aaaaaaaaaaaaaa;
這一個句子,前面的正則表達式需要嘗試function這一組的匹配,在分號位置匹配失敗之后退到匹配的開始位置。然后再嘗試匹配property這一組,在同一個位置匹配失敗,然后回溯到起點,最后才成功匹配variable這一組。換句話說,對于這句話來說,幾乎每一個字符都被比較和匹配了三次。如果問題更復雜一點,這樣的寫法可能就會存在多個地方需要回溯匹配,效率就更低下了。而后面一種寫法,在每個地方都是確定的,如果不能夠匹配的話,整個匹配就必然失敗,而完全不需要回溯。
注意上面所有A|B的關系的地方都會用(?>A|B)的形式來指定,如果匹配成功了,就不會再回溯到原來的地方嘗試另外一種可能。在正則表達式里面,總是會嘗試最大匹配,如果不使用(?>A|B)的形式的話。這是什么意思呢?
留給大家思考吧。
總結
以上是生活随笔為你收集整理的用正则表达式捕获标识符——随便说的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: asp.net小技巧:摆脱路径的困扰(二
- 下一篇: 部署 Halo 博客系统