距離弄懂正則的環視,你只差這一篇文章

在這裏插入圖片描述
上一篇文章《正則表達式匹配素數的原理講解》寫完之後,一些同學給我留言說對於正則表達式的環視不是很理解;希望我能夠講解一下關於環視部分的內容。那麼這篇文章的目的就是幫助大家理解什麼是環視,環視有什麼作用,以及在實際的開發中的一些例子。相信閱讀本文之後,大家對於正則的環視會有更深入的理解。

正則表達式的環視是什麼

環視顧名思義就是環顧四周,向左看看向看看,找一個合適的位置。環視匹配的是一個位置而不是字符,這點尤爲重要。

那麼我們是怎麼找到這個合適的位置的呢?當然是根據環視裏面包含的條件去尋找這個位置。接下來我會用生活中的一些場景來解釋每一種環視。

肯定的順序環視

假如你現在是一名叫張三的學生,現在是體育課需要大家排個隊,你記性不好忘記了自己之前的位置,但是你還記得你的後面是李四。所以這個時候你肯定先找到李四,然後站在他的前面就可以了。所以你這個選擇背後的邏輯是,我站的這個位置後面需要是李四纔可以,我們可以用下面這個圖來表示你的選擇。

(?=李四)

如果我們使用正則表達式來表示這個位置的話,那就是(?=李四),這就表示了你想要找的位置。

首先解釋一下什麼是順序環視,什麼是逆序環視。因爲正則表達式的匹配過程是從左到右的,所以如果我們要判斷一個位置的右邊滿不滿足某個條件,這就叫順序環視。如果我們判斷一個位置的左邊滿不滿足某種條件的話,這就叫做逆序環視。

你可能會覺得上面這個正則表達式有點難記,首先我們需要知道環視都是以(?作爲開頭的,然後接下來的一到兩個符號表明是那種環視,再然後就是需要滿足的條件,最後是一個)表示結束。(?=條件)可以這樣理解,?表示疑問,=表示是否滿足匹配。也就是當前位置是否滿足給出的條件。

我們來實踐一下吧,假如b表示李四,你能否找出張三需要站的位置呢?

(?=b)

否定的順序環視

假如你現在是一名叫張三的學生,現在是體育課需要大家排個隊,但是你不想讓李四站在你的後面,因爲他總是喜歡用中性筆在你的後背上亂塗亂畫😂。所以這個時候你會怎麼選擇位置呢?你肯定先看一個位置,只要這個位置的後面不是李四就可以了。因爲就算李四在你前面也無所謂,畢竟他不能畫你的後背了。

所以你做這個選擇背後的邏輯是,只有你站的這個位置後面不是李四纔可以。我們可以用下面這個圖來表示你的選擇。

(?!李四)

上面這個位置可以用正則表達式(?!李四)來表示,作爲程序開發者,我們對!很熟悉,在這裏也是同樣的意思。表示不能夠滿足後面的條件。

我們來實踐一下吧,假如b表示李四,你能否找出張三需要站的位置。

(?!李四)

肯定的逆序環視

假如你現在是一名叫張三的學生,現在是體育課需要大家排個隊,你記性還是很不好忘記了自己之前的位置,但是你還記得你前面是李四。所以這個時候你肯定先找到李四,然後站在他的後面就可以了。所以你這個選擇背後的邏輯是,我站的這個位置前面需要是李四纔可以
我們可以用下面這個圖來表示你的選擇。

(?<=李四)

如果我們使用正則表達式來表示這個位置的話,那就是(?<=李四),這就表示了你想要找的位置。(?<=條件)可以這樣理解,?表示疑問,<表示方向是當前位置的左邊,=表示是否滿足匹配。也就是當前位置的左邊是否滿足給出的條件。

我們來實踐一下吧,假如b表示李四,你能否找出張三需要站的位置。

(?<=b)

否定的逆序環視

假如你現在是一名叫張三的學生,現在是體育課需要大家排個隊,你是一個比較調皮的孩子,總喜歡在李四的後背上亂塗輪畫😂。現在老師說你站在那裏都可以,但是就是不可以讓李四站在你的前面。

這時候你該如何選擇,你肯定先找一個位置,然後確定你前面不是李四就可以了。哪怕李四在你的後面,你也不能夠在李四的後背上亂塗亂畫了

所以你這個選擇背後的邏輯是,我站的這個位置前面不能夠是李四纔可以。我們可以用下面這個圖來表示你的選擇。

(?<!李四)

如果我們使用正則表達式來表示這個位置的話,那就是(?<!李四),這就表示了你想要找的位置。(?<!條件)可以這樣理解,?表示疑問,<表示方向是當前位置的左邊,!表示不匹配。也就是當前位置的左邊不能夠匹配給出的條件。

我們來實踐一下吧,假如b表示李四,你能否找出張三需要站的位置。

(?<!b)

如果你看到得了到這裏,那麼你應該知道了這四種環視的表示方法,和它們表示的含義了。接下來我們來看一下環視在實際開發中的應用吧。

環視在實際開發中的應用

數字千分位的處理

在實際的開發中,作爲一個前端,經常需要把原始數據處理的美觀一些,然後再展示給用戶,數字的千分位添加逗號就是一個很常見的需求。

這個問題的解決方案有很多種,使用正則表達式來解決這個問題是個很不錯的方案。而且這個正則表達式要使用到我們今天學習的環視。那麼我們該怎麼使用環視去解決這個問題呢?

當我們使用正則表達式去解決問題的時候,第一件事情就是需要明確解決的是一個什麼問題。對於這個問題來說,我們要解決的問題是匹配一些位置。什麼位置?就是一個數字,從後向前數,每隔三個數字的位置,並且每個位置的左邊都需要有數字。

當我們明確了我們需要解決的問題之後,我們就可以寫我們的正則表達式。首先寫一個能夠匹配每隔三個數字的位置。這個比較容易我們可以使用肯定的順序環視(?=\d{3})應該是我們比較容易想到的。這個正則表示的意思就是匹配一個位置,這個位置的後面需要是三個數字。我們可以看一下我們匹配的結果。

(?=\d{3})

滿足上面條件的位置有好幾個,但是有一些不是我們想要的。比如5和6之間的位置就不是我們想要的,但是因爲這個位置後面是678,也滿足我們上面的正則表達式,所以是能夠匹配的。那麼我們應該如何排除這些不想要的位置呢?

還有一個隱藏的條件,那就是我們還需要匹配字符串的結尾。如果我們把上面的正則表達式修改爲(?=\d{3}$),這樣就限定了我們匹配的位置,這個位置的後面是三個數字,然後就是字符串的結尾。我們看一下這個表達式的匹配結果。

(?=\d{3}$)

當我們限定了最開始匹配的位置之後,現在就找到了一個正確的位置。但是還沒有達到我們的要求,我們還需要找到3和4之間的位置。這個時候我們可以使用量詞來解決這個問題,我們知道3和4之間的位置距離字符串的結尾有6個數字,是3的倍數,所以我們需要能夠匹配數字的個數是3、6、9等,只要是3的倍數就可以。所以我們可以將上面的表達式修改爲(?=(\d{3})+$)+作用於前面括號括起來的\d{3},表示至少需要有一個\d{3}。我們來看一下這次表達式的匹配結果。

(?=(\d{3})+$)

這次的匹配結果好像還有點問題,那就是數字的開頭也被匹配了,但是這不是我們想要的結果。那麼我們應該怎麼處理呢?一些同學可能會說,我們只要保證每一個的位置左邊至少有一個數字就可以了。嗯,這個方法也是可以的,按照這個思路,我們會寫出下面的正則表達式(?<=\d)(?=(\d{3})+$)(?<=\d)是肯定的逆序環視,表示當前位置的左邊需要是一個數字。我們來看一下這個正則表達式的匹配結果。

(?<=\d)(?=(\d{3})+$)

這次這個正則表達式終於滿足了我們的需求,匹配出了正確的位置。如果你覺得上面的正則表達式有點長的話,我們還可以使用\B來替換掉(?<=\d)。結果也是一樣的,聰明的你知道爲什麼嗎?在文章下面留言跟大家一起分享你的見解吧。

關於正則表達式的環視到這裏就結束啦,如果大家有什麼疑問和建議都可以在這裏提出來。歡迎大家關注我的公衆號「關山不難越」,我們一起學習更多有用的正則知識,一起進步。

關山不難越

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章