談談正則表達式中的“.”

寫于2015年5月7日,可能已過時,請謹慎參考。

今天分享一個小的知識點,一個正則表達式方面的很容易被人忽視的坑。

我們知道,正則表達式中,可以用.表示任意單個字符,但在underscore和jquery的源代碼中,我們可以看到,這些著名類庫的代碼中,經常并不是用.來表示任意字符,而是使用[\w\W]或者[\s\S]。乍一看,好像表達的含義是一樣的,可是為什么放著簡單的方法不用,而去多繞個圈子?今天就簡單說說這個問題。

首先我們必須要正確理解.的含義。其實說它表示任意單個字符,可能會讓人產生誤解,必須要強調一下,這個“任意單個字符”不包括控制換行的字符,也就是不包含\n\r\u2028\u2029這幾個字符。而\W\s中是能夠包含這些字符的。那個這兩種寫法的差異也就很清晰了,就是能否匹配到幾個換行控制符的差異。

那么在什么時候我們需要考慮這幾個換行控制符呢?當要處理的字符串可能包含換行時。這樣的情景太多了,處理html字符串、處理template、Node.js讀取文本等等。

提及多行文本的場景,我們很容易想到正則表達式的m模式(多行模式)。那么多行模式對我們今天討論的問題有影響嗎?我不是很確定。為什么不確定呢?有些人信誓旦旦地聲稱單行模式下 . 的含義與多行模式下不同,單選模式下等同于[\w\W]或者[\s\S],而多行模式下會排除換行控制符。但據我試驗,以及參考MDN的說法,這是不對的。的確有很多語言的正則表達式會有上述特性,但在javascript中我沒有看到,不知道會不會有瀏覽器方面的差異。那么多行模式對于javascript而言影響的是什么呢?我認為僅僅是改變了^$標識的含義:單行模式下,分別表示整個字符串的開始的結尾;多行模式下表示每一行的開始和結尾。而不管多行模式還是單行模式,我認為.都是不包含換行控制字符的,等價于[^\n\r\u2028\u2029]

再多延伸一點點,對于現代瀏覽器,可以直接用[^]來匹配任意字符的。

例子不想寫了,有興趣的可以自己試驗一下,分別用/.*/g/^.*$/g/.*/gm/^.*$/gm來匹配一下"abc\nedf",其中道理不言自明。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容