
Ben Forta
正則表達式是一種威力無比強大的武器,幾乎在所有的程序設計語言裏和計算機平臺上都可以用它來完成各種複雜的文本處理工作。本書從簡單的文本匹配開始,循序漸進地介紹了很多複雜內容,其中包括回溯引用、條件性求值和前後查找,等等。每章都爲讀者準備了許多簡明又實用的示例,有助於全面、系統、快速掌握正則表達式,並運用它們去解決實際問題。本書適合各種語言和平臺的開發人員。
這本書對正則表達作了比較詳細的解釋。 其實正則表達不是新概念,應該是軟件編寫的一種思想方法。 對於軟件程序員,是不可或缺的一種規則。這樣,在搜索文本時,就會更加準確。
不錯!簡單易懂。就是示例給的都是圖片,不好複製出來自己操作,是代碼塊就好了
挺好的一本入門書。循序漸進,一步一步提出新問題,引出一個個新解決方案,不知不覺就看完了。正則表達式適合集中一個時間一口氣讀完,如果中間停頓太多太長,思路容易接不上。看完後再去根據具體需要重讀部分內容。
很不錯的一本書!尤其適合初學者。認真學完這本書,至少在平時的工作中,我們可以把正則表達式作爲文本處理的利器,來提升我們的開發效率。 但是,整本書涉及到的知識點比較基礎,基本只說了有哪些,如何用。至於底層的爲什麼,並沒有說。所以如果有人想深入瞭解正則表達式的話,這本書就不能滿足你的要求啦。
正則表達式是一些用來匹配和處理文本的字符串,其兩種基本用途是文本內容的搜索和替換. 匹配任何字符\ 對字符進行轉義[] 字符集合匹配- 作用於字符集,字符區間方式定義字符集^ 作用於字符集,排除字符集中定義的字符\r\n 匹配空白行\d 匹配數字字符,等價於[0-9]\D 匹配非數字字符,等價於[^0-9]\w 匹配字母數字,等價於[a-zA-Z0-9_]\W 匹配非字母數字,等價於[^a-zA-Z0-9_]\s 匹配空白字符,等價於[\f\n\r\t\v]\S 匹配非空白字符,等價於[^\f\n\r\t\v] 貪婪型元字符:在進行匹配時的行爲模式是多多益善而不是適可而止的。它們會盡可能地從一段文本的開頭一直匹配到這段文本的末尾,而不是從這段文本的開頭匹配到碰到第一個匹配時爲止。懶惰型元字符:匹配儘可能少的字符,只需要給貪婪型元字符加上一個 ? 後綴即可 + +? 匹配字符或字符集合的一次或多次重複出現,最少也要匹配一個,等價於{1,}* *? 匹配字符或字符集合連續出現零次或多次,等價於{0,}? ?? 匹配字符或字符集合的零次或一次,最多不超過一次,等價於{0,1}{n, m} {n, m}? 匹配字符或字符集合最少 n 次最多 m 次{n,} {n,}? 匹配字符或字符集合最少 n 次{n} {n}? 匹配字符或字符集合 n 次 位置匹配單詞邊界:\b用來指定一個單詞邊界(\B剛好相反)。一個能夠用來構成單詞的字符(字母、數字和下劃線,也就是與\w相匹配的字符)和一個不能用來構成單詞的字符(也就是與\W相匹配的字符)之間。例如:\bcat\b。\B將匹配一個前後都不是單詞邊界的連字符字符串邊界:用來定義字符串邊界的元字符有兩個:一個是用來定義字符串開頭的^,另一個是用來定義字符串結尾的$。模式^.*$是一個在語法上完全正確的正則表達式;它幾乎總能找到一個匹配,但沒有任何實際用途。分行匹配:(? m)記號就是一個能夠改變其他元字符行爲的元字符序列。分行匹配模式將使得正則表達式引擎把行分隔符當做一個字符串分隔符來對待。在分行匹配模式下,^不僅匹配正常的字符串開頭,還將匹配行分隔符(換行符)後面的開始位置(這個位置是不可見的);類似地,$不僅匹配正常的字符串結尾,還將匹配行分隔符(換行符)後面的結束位置。例如:(?m)^\s*//.*$,匹配多個單行註釋子表達式子表達式是把一個表達式劃分爲一系列子表達式的目的是爲了把那些子表達式當作一個獨立元素來使用。子表達式必須用(和)括起來。(和)是元字符。如果需要匹配(和)本身,就必須使用它的轉義序列\(和\)。把必須匹配的情況考慮周全並寫出一個匹配結果符合預期的正則表達式很容易,但把不需要匹配的情況也考慮周全並確保它們都將被排除在匹配結果以外往往要困難得多。 回溯引用回溯引用允許正則表達式模式引用前面的匹配結果(具體到這個例子,就是前面匹配到的單詞),匹配 H 標籤例子:<[hH]([1-6])>.*?</[hH]\1>。\1到底代表着什麼?它代表着模式裏的第1個子表達式,\2代表着第2個子表達式、\3代表着第3個;依次類推。子表達式用來定義字符或表達式的集合。除了可以用在重複匹配操作中以外(詳見第7章),子表達式還可以在模式的內部被引用。這種引用被稱爲回溯引用。回溯引用的語法在不同的正則表達式實現裏有很大的差異。回溯引用在文本匹配和文本替換操作裏非常有用。 向前查找向前查找指定了一個必須匹配但不在結果中返回的模式。向前查找實際就是一個子表達式,而且從格式上看也確實如此。從語法上看,一個向前查找模式其實就是一個以 ?= 開頭的子表達式,需要匹配的文本跟在=的後面。任何一個子表達式都可以轉換爲一個向前查找表達式,只要給它加上一個 ?= 前綴即可。在同一個搜索模式裏可以使用多個向前查找表達式,它們可以出現在模式裏的任意位置(而不僅僅是出現在整個模式的開頭 向後查找向後查找操作符是 ?<=,向前查找模式的長度是可變的,它們可以包含.和+之類的元字符,所以它們非常靈活。而向後查找模式只能是固定長度——這是一條几乎所有的正則表達式實現都遵守的限制。正向前查找要用(?=)來定義,負向前查找要用(?!)來定義。有些正則表達式實現還支持正向後查找(相應的操作符是(?<=))和負向後查找(相應的操作符是(?<!))。
書寫的挺好,通俗易懂,推薦閱讀,簡單總結如下: 單字符匹配 ●abc字符串匹配abc字符串本身 ●.可以匹配任何字符 ●\是轉義字符,比如匹配.本身,這麼寫\. ●[]來定義字符集合,其本身無意義,比如[sa]表示匹配s或a ●字符集合可以用字符區間表示,比如[0123456789]和[0-9]等價,[A-Z],匹配從A到Z的所有大寫字母。[a-z],匹配從a到z的所有小寫字母。[A-F],匹配從A到F的所有大寫字母。 ●-(連字符)是一個特殊的元字符,作爲元字符它只能用在[和]之間。在字符集合以外的地方,-只是一個普通字符,只能與-本身相匹配。 ●在同一個字符集合裏可以給出多個字符區間,如[A-Za-z0-9]匹配所有大小寫字母和數字。 ●用元字符^來表明你想對一個字符集合進行取非匹配。[^0-9]匹配的是任何不是數字的字符。 ●^的效果將作用於給定字符集合裏的所有字符或字符區間,而不是僅限於緊跟在^字符後面的那一個字符或字符區間。 ●在一個完整的正則表達式裏,轉義字符\的後面永遠跟着另一個字符。 ●空白元字符:\n 換行符,\r 回車符,\t 製表符(Tab鍵),\f 換頁符,\v 垂直製表符,[\b] 回退(並刪除)一個字符(backspace鍵) ●如果要把文本里的空白行去掉,使用\r\n\r\n,其中\r\n匹配一個“回車+換行”組合,使用正則表達式\r\n\r\n進行的搜索將匹配兩個連續的行尾標籤,而那正是兩條記錄之間的空白行。 ●Unix和Linux系統只使用一個換行符來結束一個文本行;換句話說,在Unix/Linux系統上匹配空白行只使用\n\n即可,不需要加上\r。 ●元字符讓正則表達式看起來更簡潔,如匹配任何一個數字字符 \d 等價於[0-9],匹配任何一個非數字字符 \D 等價於[^0-9] ●\w表示匹配任何一個大小寫字母、數字、下劃線,等價於[A-Za-z0-9_],\W表示匹配任何一個非大小寫字母、數字、下劃線,等價於[^A-Za-z0-9_] ●空白字符元字符,\s表示匹配任何一個空白字符,等價於[\f\r\n\t\v],\S表示匹配任何一個非空白字符,等價於[^\f\r\n\t\v] ●在正則表達式裏,十六進制(逢16進1)數值要用前綴\x來給出。比如說,\x0A對應於ASCII字符10(換行符),其效果等價於\n。八進制(逢8進1)數值要用前綴\0來給出,數值本身可以是兩位或三位數字。比如說,\011對應於ASCII字符9(製表符),其效果等價於\t。(不常用) ●POSIX字符類,寫法[[:xdigit:]],是中括號加上冒號,如 [:alnum:] 等價於 [A-Za-z0-9],[:alpha:] 等價於 任何一個字母,[:blank:] 等價於 空格或製表符[\t ],後邊有一個空白字符,[:cntrl:] 等價於 ascii控制字符,[:digit:] 等價於 任何一個數字,[:print:] 等價於 任何一個可打印字符,[:graph:] 等價於 [:print:]但不包括空格,[:lower:] 等價於 任何一個小寫字母,[:upper:] 等價於 任何一個大寫字母,[:punct:] 等價於 既不屬於[:alnum:]又不屬於[:cntrl:]的任何字符,[:space:] 等價於 任何一個空白字符[\f\r\n\t\v ],後邊有一個空白字符,[:xdigit:] 等價於 任何一個十六進制數字[A-Fa-f0-9] 重複匹配 ●匹配一個或多個字符,a+將匹配一個或多個連續出現的a。類似地,[0-9]匹配任意單個數字,[0-9]+將匹配一個或多個連續的數字。+是一個元字符。如果需要匹配+本身,就必須使用它的轉義序列\+。但是如果+位於[]中則不一定要轉義(.也同理)。 ●匹配零個或多個字符,使用*元字符,*的用法與+完全一樣——只要把它放在一個字符(或一個字符集合)的後面,就可以匹配該字符(或字符集合)連續出現零次或多次的情況。.*表示匹配任意字符。 ●匹配零個或一個字符,使用?元字符,?只能匹配一個字符(或字符集合)的零次或一次出現,最多不超過一次。 ●元字符{和},重複次數要用{和}字符來給出——把數值寫在它們之間。表示前一個字符或字符集需要連續出現n次才能匹配上。 ●{}語法還可以用來爲重複匹配次數設定一個區間——也就是爲重複匹配次數設定一個最小值和一個最大值。這種區間必須以{2, 4}這樣的形式給出——{2, 4}的含義是最少重複2次、最多重複4次。 ●爲避免不必要的麻煩,在需要匹配/字符本身的時候,最好總是使用它的轉義序列\/。 ●匹配“至少重複多少次”,{3, }表示至少重複3次,與之等價的說法是“必須重複3次或更多次”。 防止過度匹配 ●+和*都是“貪婪型”元字符,它們在進行匹配時的行爲模式是多多益善而不是適可而止的。它們會盡可能地從一段文本的開頭一直匹配到這段文本的末尾,而不是從這段文本的開頭匹配到碰到第一個匹配時爲止。 ●懶惰型元字符的寫法很簡單,只要給貪婪型元字符加上一個?後綴即可。(“懶惰”在這裏的含義是匹配儘可能少的字符——與“貪婪型”元字符的行爲模式剛好相反)如 *?,+?,{n,}? 位置匹配 ●位置匹配用來解決在什麼地方進行字符串匹配操作的問題。 ●單詞邊界,\b用來匹配一個單詞的開始或結尾。單詞cat的前後都有一個空格,而這將與模式\bcat\b相匹配(空格是用來分隔單詞的字符之一)。單詞scattered中的字符序列cat不能與這個模式相匹配,因爲它的前一個字符是s、後一個字符是t(這兩個字符都不能與\b相匹配)。如果你想匹配一個完整的單詞,就必須在你想要匹配的文本的前後都加上\b限定符。模式\bcap將匹配以字符序列cap開頭的任何一個單詞。模式cap\b將匹配以字符序列cap結束的任何一個單詞。 ●如果你想表明不匹配一個單詞邊界,請使用\B。即非字母數字下劃線的邊界,如xx - xx想匹配-使用\B-\B。同一個元字符的大寫形式與它的小寫形式在功能上往往剛好相反。 ●字符串邊界,^匹配一個字符串的開頭位置,所以^\s*將匹配一個字符串的開頭位置和隨後的零個或多個空白字符(這解決了<? xml>標籤前允許有空格、製表符、換行符等空白字符的問題)。\s*$匹配一個字符串結尾處的零個或多個空白字符。 ●分行匹配模式,在使用時,(? m)必須出現在整個模式的最前面。^\s*//.*$將匹配一個字符串的開始,然後是任意多個空白字符,再後面是//(JavaScript代碼裏的註釋標籤),再往後是任意文本,最後是一個字符串的結束。不過,這個模式只能找出第一條註釋(並認爲這條註釋將一直延續到文件的末尾,因爲*是一個“貪婪型”元字符)。加上(? m)前綴之後,(? m)^\s*//.*$將把換行符視爲一個字符串分隔符,這樣就可以把每一行註釋都匹配出來了。 使用子表達式 ●把一個表達式劃分爲一系列子表達式的目的是爲了把那些子表達式當作一個獨立元素來使用。子表達式必須用(和)括起來。和)是元字符。如果需要匹配(和)本身,就必須使用它的轉義序列\(和\)。 ●匹配ip地址,常規做法\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3},使用(和)元字符後(\d{1,3}\.){3}\d{1,3} ●匹配1987-01-01的1987或2023使用(19|20)\d{2},不能使用19|20\d{2},因爲|表示或,分開的是該符號前後的兩部分。 ●子表達式允許嵌套。事實上,子表達式允許多重嵌套,這種嵌套的層次在理論上沒有限制,但在實際工作中還是應該遵循適可而止的原則。 回溯引用 ●例子:匹配html中的所有h標題,這裏使用的是.*?(懶惰型)而不是.*(貪婪型)。*和其他幾個元字符是“貪婪型”元字符,所以模式<[hH][1-6]>.*</[hH][1-6]>有可能會從第2行的<H1>一直匹配到第6行的</H2>,這可不是我們想要的結果;使用“懶惰型”元字符.*?解決了這個問題。這個特定的例子裏即便是使用了“貪婪型”元字符也不一定會有問題。一般來說,元字符.不匹配換行符,而上例中的每個標題都各自佔據一行。 ●如果有不匹配的標籤如html中的<h2>和</h3>的錯誤組合,使用<[Hh][1-6]>.*?</[Hh][1-6]>無法精準的判別這種組合,就要用到回溯引用。 ●假設你有一段文本,你想把這段文本里所有連續重複出現的單詞(打字錯誤,其中有一個單詞輸了兩遍)找出來。顯然,在搜索某個單詞的第二次出現時,這個單詞必須是已知的。回溯引用允許正則表達式模式引用前面的匹配結果(具體到這個例子,就是前面匹配到的單詞)。 ●回溯引用只能用來引用模式裏的子表達式(用(和)括起來的正則表達式片段)。回溯引用匹配通常從1開始計數(\1、\2,等等)。在許多實現裏,第0個匹配(\0)可以用來代表整個正則表達式。比如a block of of text and and sth找出重複出現的單詞,使用[ ]+(\w+)[ ]+\1匹配,[ ]+匹配一個或多個空格,\w+匹配一個或多個字母數字字符,[ ]+匹配隨後的空格。注意,\w+是括在括號裏的,它是一個子表達式。這個模式的最後一部分是\1;這是一個回溯引用,而它引用的正是前面劃分出來的那個子表達式:當(\w+)匹配到單詞of的時候,\1也匹配單詞of;當(\w+)匹配到單詞and的時候,\1也匹配單詞and。回溯引用指的是模式的後半部分引用在前半部分中定義的子表達式。\1到底代表着什麼?它代表着模式裏的第1個子表達式,\2代表着第2個子表達式、\3代表着第3個;依次類推。於是,在上面那個例子裏,[ ]+(\w+)[ ]+\1將匹配同一個單詞的連續兩次重複出現。上邊html例子中使用<[Hh]([1-6])>.*?</[Hh]\1>來排除h2和h3組合的情況,用(和)把[1-6]括了起來,使它成爲了一個子表達式。這樣一來,我們就可以在用來匹配標題結束標籤的</[hH]\1>用\1來引用這個子表達式了。子表達式([1-6])匹配數字1~6, \1只匹配與之相同的數字。這樣一來,原始文本里的<H2>This is not valid HTML</H3>就不會被匹配到了。 ●回溯引用在替換操作中的應用,比如文本中把郵箱地址[email protected]變爲超鏈接,即<A HREF="mailto:[email protected]">[email protected]</A>,替換操作需要用到兩個正則表達式:一個用來給出搜索模式,另一個用來給出匹配文本的替換模式。回溯引用可以跨模式使用,在第一個模式裏被匹配的子表達式可以用在第二個模式裏。這裏使用的模式(\w+[\w\ .]*@[\w\ .]+\ .\w+)與我們以前使用的完全一樣(匹配電子郵件地址),但這次把它寫成了一個子表達式。這樣一來,被匹配到的文本就可以用在替換模式裏了,<A HREF="mailto:$1">$1</A>,同一個子表達式可以被引用任意多次——只要在需要用到它的地方寫出它的回溯引用就行了。 ●在看例子,對文字進行重新排版,電話號碼被保存爲313-555-1234。現在需要把電話號碼重新排版爲(313)555-1234。(\d{3})(-)(\d{3})(-)(\d{4})用來匹配一個電話號碼,它被劃分爲5個子表達式,負責重新排版電話號碼的替換模式($1)$3-$5只用到了它們當中的3個。在對文本進行重新排版的時候,把文本分解成多個子表達式的做法往往非常有用,這可以讓我們對文本的排版效果做出更精確的控制。 ●大小寫轉換,元字符\l和\u只能把下一個字符(或子表達式)轉換爲小寫或大寫。\L和\U將把它後面的所有字符轉換爲小寫或大寫,直到遇上\E爲止。例子,把一級標題(<H1>...</H1>)的標題文字轉換爲大寫,模式(<[Hh]1>)(.*?)(</[Hh]1>)把一級標題分成了3個子表達式,然後替換$1\U$2\E$3 前後查找 ●前後查找的作用:比如只想返回被匹配的html標籤裏邊的內容,不需要返回標籤本身 ●向前查找,從語法上看,一個向前查找模式其實就是一個以?=開頭的子表達式,需要匹配的文本跟在=的後面。比如匹配url中的協議名,使用.+(?=:),模式.+匹配任意文本(第1個匹配是http),子表達式(? =:)匹配:。注意,被匹配到的:並沒有出現在最終的匹配結果裏;我們用?=向正則表達式引擎表明:只要找到:就行了,不要把它包括在最終的匹配結果裏——用術語來說,就是“不消費”它。模式.+(:)查找到並且匹配結果包含:,模式.+(? =:)查找到但匹配結果不包含:。 ●向後查找,操作符是?<=。比如匹配價格$236.85,使用\$[0-9.]+,不想要$只要236.85使用(?<=\$)[0-9.]+,(? <=\$)只匹配$,但不消費它;最終的匹配結果裏只有價格數字(沒有前綴的$字符)。向前查找模式的長度是可變的,它們可以包含.和+之類的元字符,所以它們非常靈活。而向後查找模式只能是固定長度——這是一條几乎所有的正則表達式實現都遵守的限制。 ●結合向前向後查找,匹配<title>This is a title</title>中的純text使用 (? <=<[tT][iI][tT][lL][eE]>).*(? =</[tT][iI][tT][lL][eE]>) ,其中(? <=<[tT][iI][tT][lL][eE]>)是一個向後查找操作,它匹配(但不消費)<TITLE>;而(? =</[tT][iI][tT][lL][eE]>)是一個向前查找操作,它匹配(但不消費)</TITLE>。最終返回的匹配結果包含且僅包含標題文字(用術語來說,就是隻有標題文字被消費了)。 ●對前後查找取非,負向前查找(negative lookahead)將向前查找不與給定模式相匹配的文本,負向後查找(negative lookbehind)將向後查找不與給定模式相匹配的文本。正向前查找(?=),負向前查找(?!),正向後查找(?<=),負向後查找(?<!),例子:在一個包含$30,368這兩種類型的文本里,只匹配金額使用(?<=\$)\d+,只查找數量使用表達式(? <! \$)是一個負向後查找,它使得最終的匹配結果只包含那些不以$開頭的數值。 嵌入條件 ●匹配電話號碼的例子,(\( )?也匹配一個可選的左括號,但我們這次把它用括號括起來得到了一個子表達式。隨後的\d{3}匹配一位數字的區號。(?(1)\)|-)是一個回溯引用條件,它將根據條件是否得到滿足而去匹配)或-——如果(1)存在(也就是找到了一個左括號), \)必須被匹配;否則,-必須被匹配。這樣一來,只有配對出現的括號纔會被匹配; 應用 ●MySQL對正則表達式的支持體現在允許在WHERE子句裏使用如下格式的表達式:SELECT * FROM table WHERE REGEXP "pattern" 注意:正則匹配是區分字母大小寫的
# Meta - 正則表達式入門級別的一本不錯的書, 更像是一本用戶入門學習手冊而非一本字典級參考手冊, 正如作者所說, 在學習和使用正則表達式的時候,重要的並不是你知道多少個特殊字符,而是你會不會運用它們去解決實際問題, 學以致用, 致用以學, 最近我的問題在於爲了學習而學習, 而非爲了應用而學習, 事倍功半, 人的精力有限, 時間有限, 又哪能做到樣樣深耕呢, 對於接觸的大多領域都只需掌握一些核心概念和基本語法就好 # 正則表達式必知必會 - 本書架構, 從簡單的字符串匹配開始入手, 後序介紹一些複雜一些的專題, e.g. 回溯引用/後向引用(backreference), 條件性求值(conditional evaluation)和前後查找(looking-around) ## C1 正則表達式入門 - regular expression -> regex - 用途, 進行文本匹配+[替換] - 比較迷你, 一般嵌入到其他工具中, 應用程序大多用菜單訪問regex, 程序設計語言大都通過函數or類來使用regex - 計算機從來都是做中學學科, 不經過實踐的學習在CS領域事倍功半 ## C2 匹配單個字符 - . 除換行符以外的任意單個字符, 如果需要.的本身含義, 用轉義字符\ ## C3 匹配一組字符 - 用[]定義一個字符集合, 裏面可以寫想要匹配的字符, e.g. [ab], - 在[]中使用-可以定義一個字符區間, e.g. [A-Za-z0-9] 在[]外使用-就是一個普通的字符, 所以在regex中使用-不需要被轉義 - [^a-z0-9], 先定義一個字符區間, 而後對其取非, 而不是隻對^後跟着的字符區間取非 ## C4 使用元字符 - 前面接觸到的元字符, `. [ ] \` - 空白元字符 - [\b] 回退(並刪除)一個字符(Backspace鍵), 這個是用來匹配退格字符的, 不在\s中 - \f 換頁符 - \n 換行符, \r 回車符, \t 製表符 - \v 垂直製表符 - \d is [0-9], \D is [^0-9] - \w is [a-zA-Z0-9_], \W is ^ of \w - \s is [\f\n\r\t\v], 任意一個空白字符, \S任意非空字符 - POSIX字符類, 一種字符集合中的簡寫形式, 並非所有的regex的實現都支持 ## C5 重複匹配 - +, 一到多, [0-9]+, 代表1-多個連續數字 - 注意區分[0-9+], 匹配一個字符, 可以是數字或+ - *, 零到多 - ?, 0 or 1 - 解決Windows/Linux系統下回車問題就可以用 [\r]?\n - 寫\r?\n也是一樣的, 第一種寫法定義一個字符集合, 集合裏只有\r這樣的一種字符, 和第二種寫法功能相同, 對讀者更友好一點, 讀起來不會有歧義. - 上述三種都是元字符, 匹配本身需要轉義, 放到字符集合裏也是本身, 加了轉義也沒什麼問題 - 制定精確的重複次數{} - {a} 重複a次 - {a, b} 重複[a, b]次 - {a, } 至少重複a次 - *, +, {a, }這三個都沒有上限, 都是貪婪型的, 儘可能匹配的長 - *?, +?, {a, }?是其對於的懶惰版本, 儘可能匹配的短 ## C6 位置匹配 - the border of a word(w in Vim) - \< matches the pos of \W and \w, \> matches that of \w and \W - \b matches the pos of \w and \W or that of \W and \w - the border of a string(W in Vim) - ^ matches the start of a string, $ matches end - (?m), regard \n as a start/end of string ## C7 子表達式 - 用元字符()進行分組 ## C8 回溯引用backreference - 解決HTML中Head標籤匹配, 用`<[hH][1-6]>.*?</[hH][1-6]>`來找出所有的head標籤, 現在存在的問題是<h2>a</h3>也會被匹配進來, 也就是結束標籤對開始標籤的情況一無所知, 回溯引用就是用來解決這類問題的 - 比如匹配兩個連續的單詞怎麼實現, 需要先知道第一個單詞是什麼, 才能控制第二個和它一不一樣, 實現 `[ ]+(\w+)[ ]+\1` - [ ]+代表1-多個space, 用()把\w+括起來, 做成一個子表達式, 然後用\1引用pattern中的第一個子表達式, 想一下Java中對正則表達式的實現, 把子表達式的sIndex和eIndex+1存到groups[2]和groups[3]中, 後續即可引用 - 這種按位置的捕獲方式用\數字進行引用, 當想改邏輯的時候可能要改的地方有點多, 可以用`命名捕獲`, 給子表達式起個名字, 這樣改變相對位置也不用改後面引用位置的語句了, 命名捕獲是否支持要看具體的實現 ## C9 前後查找lookaround - regex常見的實現都支持向前查找lookahead, 部分支持向後查找lookbehind, Java是支持的 ## C10 嵌入條件 - 當前面是不同的匹配時向後找不同的匹配, 類似於編程語言中的三元運算符 ## 附錄A ### A.12 Perl - m/pattern/ - s/pattern/pattern/
這本書太棒了。我之前是在網上看過正則表達式的文章,雖然都看得懂,但就是不能靈活運用,符號記憶也不深刻。但是這本書,從頭到尾,一步一步的讓你搞懂每個字符是幹什麼的,一步一步的讓你理解這個字符加那個字符拼在一起會怎麼樣。在這個過程中,先帶你學習知識,然後運用知識答題,再提出已有知識無法滿足的問題,引出新知識,就這樣一步一步的引導你學習,完完全全的由淺入深。總之,這本書,太棒了👏👏
瞭解什麼是正則表達式(一些用來匹配和處理文本的字符串)、其作用是輔助文本處理(完成搜索和替換)、正則表達式的語法。
可以,給的例子很全,但其實很多方法裏面還能在簡寫,沒有做拓展,但足夠了,真正的生產環境中我更喜歡看這種寫法,簡單易懂。平衡給的很好