算起來接觸正則也為時不短,看過一點正規表示式的引擎原理,素來以正則高手自詡。昨日偶然間看到乙個正規表示式的入門教程,發現裡面居然有不少東西沒見過,還有幾個正則讓我困惑不已,說起來真是慚愧。以後在博大精深的正則面前,我只會說:我剛入門。
好了,說正事。有如下的需求,有一串正整數,需要以英文格式展示,即右起每3個數按逗號隔開。正則要幹的事就是把要加逗號的部分找出來,比如123456789就是456789 ,12345就是345 。
給出乙個正規表示式,((?<=/d)/d)+/b
,這東西可大有來頭,裡面用到的
(?<=/d)在正規表示式中叫做零寬斷言(
zero-width assertions
)。那到底什麼叫做
零寬斷言
呢? 在正規表示式中有4種
零寬斷言,分別如下:
a(?=exp)前驅
正向斷言
匹配右邊的字元是否為exp,如windows(?=2)
將匹配windows2中的windows,不會匹配windows3
中的windows
a(?!exp)前
驅負向斷言
匹配右邊的字元是否不為exp
,如windows(?!=2)
將匹配windows3
中的windows
,不會匹配windows2
中的windows
(?<=exp)a
後驅正向斷言
匹配左邊的字元是否為exp
,如(?=2)
windows
將匹配2windows
中的windows
,不會匹配3windows
中的windows (?
後 驅負向斷言
匹配 左
邊的字元是否不為exp
,如(?!=2)
windows
將匹配3windows
中的windows
,不會匹配2windows
中的windows
為什麼稱為零寬斷言呢?是因為它僅僅判斷特定位置是否滿足exp匹配,然後立即丟棄該匹配,只是將匹配結果(true or false) 返回給引擎(這就是斷言 ),並不對字串的推進造成影響。如上面用
如windows(?=2)
exp匹配windows2後下乙個開始位置是
windows2中的2 ,雖然對2做了匹配,但接下來的匹配
exp
將重新匹配2(這就是零寬 )
。初看上面的**,有乙個地方可能會讓你感到困惑:按照第三列的描述,後驅和前驅應該對調才對。這樣定義是因為正在表示式是從字串左邊向右邊進行匹配,所以右邊稱為「前」,左邊稱為「後」。
有了上面的基礎,現在我們來對
((?<=/d)/d)+/b做個簡單的分析。/b 匹配詞的邊界,這裡放在最後,將匹配右邊界。
/d表示連續3個數字,前面加上斷言後表示
連續3個數字的
左邊還有數字,所以
123456789中的123和12345中的12都將被丟棄 。換成(?<=/d)(/d)+/b會更容易理解,具體分析可以由讀者自己完成。
仔細觀察上面的**,我們發現前驅斷言都出現在右邊,後驅斷言都出現在左邊。那是不是一定要這樣寫才對呢?
其實不是的,前驅、後驅都可以放在a的兩邊,只不過有個細微而且致命的區別。舉個例子,比如用(?=2)windows 來匹配windows2,將不會匹配其中的windows。這是因為
(?=2)windows
表示的是從該詞(
windows
)開始向右進行匹配,所以斷言遇到的第乙個字元將是windows中的w,直接斷言失敗。 同理
a(?<=exp)表示
從a的右邊開始向左進行匹配,即exp將首先匹配a。所以使用斷言的時候要注意位置對結果的影響。
好吧,暫時先說到這裡,順便介紹一位正則大牛,人稱:..標 哥,常年混跡於一正則q群,幾乎有問必答,答必解題,所以大家還有什麼疑問,可以在下面回帖,相信偉大的標哥會看到的。
從乙個名詞說開去
據說架構沒有乙個大家都統一認定的定義,於是我找了乙個能被絕大多數人接受的。這個定義很長,我沒心情把它都寫出來。但是有乙個地方引起了我的注意 xx執行時的聯絡 xx。這樣乙個高深的概念居然會跟這麼具體的乙個實現產生這麼密切的關聯,你難道不覺得驚奇嗎?雖然我張嘴計算的世界,閉口計算的世界,但是歸根結底這...
乙個正規表示式的例子
需求 通過.net的正則 上面3個都得到 aa 並對語句稍微講解一下。謝謝。http w 這個是我寫的。不知道怎麼加上或者匹配www 還有?這個什麼意思查不到。解決 i 匹配模式,表示忽略大小寫,在.net中等價於在後面加regexoptions.ignorecase引數 http www 肯定逆序...
乙個新人理解正規表示式
知識點 1 表單驗證 針對於 非空驗證 去空格 非空驗證是什麼呢,就是說 當我輸入乙個賬號的時候不能輸入乙個空格就完事了,乙個空格或者多個空格絕對不是賬號,我們接收乙個賬號的時候首先要做的就是把他的前後空格給去掉,然後判斷一下他是不是空的,如果是空的那麼就提示他輸入有誤。對比驗證 跟乙個值對比 就是...