首頁 web前端 js教程 什麼是單行模式? JavaScript正規的單行模式詳解

什麼是單行模式? JavaScript正規的單行模式詳解

Apr 21, 2017 am 10:20 AM

這篇文章主要介紹了JavaScript的正則也有單行模式了,需要的朋友可以參考下

正則表達式最早是由Ken Thompson 於1970 年在他改進過的QED 編輯器裡實現的,正規裡最簡單的元字元「.」 在當時所匹配的就是除換行符外的任意字元:

"." is a regular expression which matches any character except .

上面這句話出自QED 在1970 年的官方文檔,這可能是史上第一份正規文檔。

為什麼要這麼規定?是因為 QED 是以行為單位來編輯文件的,而且行尾的換行符號也算在這一行的內容裡。例如你想把一段程式碼中所有的單行註解刪掉,在QED 裡可以用下面這句指令: 

1,$s#//.*##
登入後複製

如果「.」 能配對到換行符,那麼換行符也會被刪除,會導致這些行和它的下一行合併,這通常都不是我們想要的結果,所以,“.” 在最初發明時被設計成了不能匹配換行符。雖然現在的作業系統上已經沒有 QED 指令讓我們測試了,但我們還有 VIM,VIM 裡的 “.” 也一樣不能匹配換行符,因為同樣的原因。

不像在Node 中,讀取文件通常是一股腦讀完整個文件,Perl 繼承了眾多Linux 命令按行讀取文件的傳統,像這樣:

while (<>) {print $_}
登入後複製

_ 的末尾也有換行符,所以Perl 也就很自然的繼承了QED 的「.」 不符合換行符的規定。但Perl 畢竟是門程式語言,而不是編輯器,它的正則要匹配的對像不單單會是單行文本,還可能是多行文本,因此在它的正則中,“.” 有跨行匹配的需求,因此Perl 發明了正規的單行模式/s,即讓“.” 也能匹配換行符。

Perl 中用來開啟單行模式的/s 修飾符的官方描述是“Treat the string as single line”,這個“single line” 要這麼理解:“.” 在普通模式下只能匹配行內字符,不能跨行;而在單行模式下,Perl 會假裝把多行字符串看成一行,把其中的換行符看做是行內字符,所以“.” 也就能匹配它們了。更圖像點說,就是把下面的三行文本

1
2
3
登入後複製

看成 "1\n2\n3\n" 一行文本,單行模式就是這個意思。

但要命的是,因為同樣的原因(字串變數可以包含多行文字),Perl 也發明了/m 修飾符,即多行模式,官方描述是「Treat the string as multiple lines ”,這個模式JavaScript 的正則裡自古也有,這裡這個“多行”的意思是說:^ 和$ 元字符默認不會匹配一個字符串中間的那些換行符前後的位置,即認為字符串永遠只有一行,開啟多行模式後就能配對了。

也就是說,單行模式和多行模式是針對不同的元字符的,剛接觸正則的人都會被“單行模式”和“多行模式”這兩個看似是相對應的概念,實則毫無關聯的名詞給搞暈。

後來,Ruby 的作者可能覺得“單行模式”這個正則術語起的不好,特例獨行把讓“.” 匹配換行符這一模式稱之為“多行模式”,即讓. * 之類的正則能夠匹配多行了,所以也完全講得通,修飾符也用了/m(Ruby 中默認會開啟Perl 中的“多行模式”,所以/m 沒被佔用),這真是雪上加霜,更亂了。

再後來,Python 作者可能也覺得應該避免“單行模式”這個叫法,於是起了個新的名字“dotall”,也就是讓dot 能匹配所有字符的意思,很好的名字,再後來Java 也使用了這個名字。

上面回顧了一下歷史,解釋了下單行模式的由來以及說明了下單行模式這個名字起得不好。 V8 最近剛實作了一個stage 3 的ES 提案github.com/mathiasbynens/es-regexp-dotall-flag,這個提案為JavaScript 的正則引入了/s 修飾符和dotAll 屬性,dotAll 屬性是學了Python 和Java, /s 修飾符是繼承了Perl 的,這裡也沒必要發明一個新的修飾符例如/d,只會讓事情變得更複雜。 /s 在JavaScript 的具體效果是讓「.」 能符合先前無法配對的四個行終止符:\n(換行)、\r(回車)、\u2028(行分隔符號)、\u2029(段落分隔符):


/foo/s.dotAll // true
/^.{4}$/s.test("\n\r\u2028\u2029") // true
登入後複製

其實就是個很簡單的東西,但可能一些沒有接觸過JavaScript 以外的正規的同學到時候學到這個新的模式後會產生困惑,這裡再澄清一下:多行模式控制的是^ 和$ 的表現,單行模式控制的是「.」的表現,兩者沒有直接關係。

然而當初引入單行模式和多行模式這兩個易混淆概念的Perl 語言,已經在Perl 6 中完全刪除了這兩個模式:“.” 號預設就匹配換行符,\N可以匹配換行符除外的任意字元;^ 和$ 始終匹配字串的首尾,而新引入了^^ 和$$ 兩個元字元來匹配行的首尾。

過去我們常用的單行模式的替代品[^] 或者[\s\S] 也不是完全沒有用了,比如在一些使用JavaScript 正規的編輯器裡(VS Code、Atom),不太可能給你提供開啟單行模式的介面。不過說起編輯器裡的正規功能,用JavaScript 實現的編輯器的正規功能還是太弱了,比如不能在正則自身內部開啟某些模式,比如要是在Sublime(使用Python 正則)裡的話,在正則內部使用(?s) 就能開啟dotall 模式,例如可以用(?s)/\*.+?\*/ 配對到所有的多行註解。

以上是什麼是單行模式? JavaScript正規的單行模式詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
威爾R.E.P.O.有交叉遊戲嗎?
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

如何使用WebSocket和JavaScript實現線上語音辨識系統 如何使用WebSocket和JavaScript實現線上語音辨識系統 Dec 17, 2023 pm 02:54 PM

如何使用WebSocket和JavaScript實現線上語音辨識系統引言:隨著科技的不斷發展,語音辨識技術已成為了人工智慧領域的重要組成部分。而基於WebSocket和JavaScript實現的線上語音辨識系統,具備了低延遲、即時性和跨平台的特點,成為了廣泛應用的解決方案。本文將介紹如何使用WebSocket和JavaScript來實現線上語音辨識系

WebSocket與JavaScript:實現即時監控系統的關鍵技術 WebSocket與JavaScript:實現即時監控系統的關鍵技術 Dec 17, 2023 pm 05:30 PM

WebSocket與JavaScript:實現即時監控系統的關鍵技術引言:隨著互聯網技術的快速發展,即時監控系統在各個領域中得到了廣泛的應用。而實現即時監控的關鍵技術之一就是WebSocket與JavaScript的結合使用。本文將介紹WebSocket與JavaScript在即時監控系統中的應用,並給出程式碼範例,詳細解釋其實作原理。一、WebSocket技

如何利用JavaScript和WebSocket實現即時線上點餐系統 如何利用JavaScript和WebSocket實現即時線上點餐系統 Dec 17, 2023 pm 12:09 PM

如何利用JavaScript和WebSocket實現即時線上點餐系統介紹:隨著網路的普及和技術的進步,越來越多的餐廳開始提供線上點餐服務。為了實現即時線上點餐系統,我們可以利用JavaScript和WebSocket技術。 WebSocket是一種基於TCP協定的全雙工通訊協議,可實現客戶端與伺服器的即時雙向通訊。在即時線上點餐系統中,當使用者選擇菜餚並下訂單

如何使用WebSocket和JavaScript實現線上預約系統 如何使用WebSocket和JavaScript實現線上預約系統 Dec 17, 2023 am 09:39 AM

如何使用WebSocket和JavaScript實現線上預約系統在當今數位化的時代,越來越多的業務和服務都需要提供線上預約功能。而實現一個高效、即時的線上預約系統是至關重要的。本文將介紹如何使用WebSocket和JavaScript來實作一個線上預約系統,並提供具體的程式碼範例。一、什麼是WebSocketWebSocket是一種在單一TCP連線上進行全雙工

如何用 Golang 正規匹配多個單字或字串? 如何用 Golang 正規匹配多個單字或字串? May 31, 2024 am 10:32 AM

Golang正規表示式使用管道符|來匹配多個單字或字串,將各個選項作為邏輯OR表達式分隔開來。例如:匹配"fox"或"dog":fox|dog匹配"quick"、"brown"或"lazy":(quick|brown|lazy)匹配"Go"、"Python"或"Java":Go|Python |Java匹配字或4位郵遞區號:([a-zA

JavaScript與WebSocket:打造高效率的即時天氣預報系統 JavaScript與WebSocket:打造高效率的即時天氣預報系統 Dec 17, 2023 pm 05:13 PM

JavaScript和WebSocket:打造高效的即時天氣預報系統引言:如今,天氣預報的準確性對於日常生活以及決策制定具有重要意義。隨著技術的發展,我們可以透過即時獲取天氣數據來提供更準確可靠的天氣預報。在本文中,我們將學習如何使用JavaScript和WebSocket技術,來建立一個高效的即時天氣預報系統。本文將透過具體的程式碼範例來展示實現的過程。 We

簡易JavaScript教學:取得HTTP狀態碼的方法 簡易JavaScript教學:取得HTTP狀態碼的方法 Jan 05, 2024 pm 06:08 PM

JavaScript教學:如何取得HTTP狀態碼,需要具體程式碼範例前言:在Web開發中,經常會涉及到與伺服器進行資料互動的場景。在與伺服器進行通訊時,我們經常需要取得傳回的HTTP狀態碼來判斷操作是否成功,並根據不同的狀態碼來進行對應的處理。本篇文章將教你如何使用JavaScript來取得HTTP狀態碼,並提供一些實用的程式碼範例。使用XMLHttpRequest

javascript如何使用insertBefore javascript如何使用insertBefore Nov 24, 2023 am 11:56 AM

用法:在JavaScript中,insertBefore()方法用於在DOM樹中插入一個新的節點。這個方法需要兩個參數:要插入的新節點和參考節點(即新節點將要插入的位置的節點)。

See all articles