1. 程式人生 > 程式設計 >超強變態的正則(\w)((?=\1\1\1)(\1))+講解

超強變態的正則(\w)((?=\1\1\1)(\1))+講解

這個正則出自這個網站 http://www.regexlab.com/zh/regref.htm

正向預搜尋:"(?=xxxxx)","(?!xxxxx)"

格式:"(?=xxxxx)",在被匹配的字串中,它對所處的 "縫隙" 或者 "兩頭" 附加的條件是:所在縫隙的右側,必須能夠匹配上 xxxxx 這部分的表示式。因為它只是在此作為這個縫隙上附加的條件,所以它並不影響後邊的表示式去真正匹配這個縫隙之後的字元。這就類似 "\b",本身不匹配任何字元。"\b" 只是將所在縫隙之前、之後的字元取來進行了一下判斷,不會影響後邊的表示式來真正的匹配。

點選測試 舉例1:表示式 "Windows (?=NT|XP)" 在匹配 "Windows 98,Windows NT,Windows 2000" 時,將只匹配 "Windows NT" 中的 "Windows ",其他的 "Windows " 字樣則不被匹配。

點選測試 舉例2:表示式 "(\w)((?=\1\1\1)(\1))+" 在匹配字串 "aaa ffffff 999999999" 時,將可以匹配6個"f"的前4個,可以匹配9個"9"的前7個。這個表示式可以讀解成:重複4次以上的字母數字,則匹配其剩下最後2位之前的部分。當然,這個表示式可以不這樣寫,在此的目的是作為演示之用。

例子:例如 999999999 或 666666

1、(\w)((?=\1\1\1)(\1))+

最後的+號意思是一個或多個 意思就是 666666之匹配前四個6,而999999999只匹配前面7個,後面反正要留兩個
因為用了(?=\1\1),每次只匹配兩個,但保證右側有99,每次都取兩個,每次都包括之前的一個

(\w)((?=\1\1\1)(\1))+在999999999 中實際上是被匹配了6次。
第一次:(\w)取出第一個9,(?=\1\1\1)限定第2個9到第4個9,(\1)取出第2個9,得到99
第二次:(?=\1\1\1)限定第3個9到第5個9,(\1)取出第3個9,得到999
第三次:(?=\1\1\1)限定第4個9到第6個9,(\1)取出第4個9,得到9999
第四次:(?=\1\1\1)限定第5個9到第7個9,(\1)取出第5個9,得到99999
第五次:(?=\1\1\1)限定第6個9到第8個9,(\1)取出第6個9,得到999999

第六次:(?=\1\1\1)限定第7個9到第9個9,(\1)取出第7個9,得到9999999

2、(\w)((\1)(?=\1\1))+

第一次 \w取出第一個9,\1再取1個9就是 99 後面緊跟兩個9才符合條件 所有第一次就是99
第二次 從第3個9到第四個9, 開始就\1 再取一個 999
第三次 匹配從第4-6個9 取一個 9999
第四次 從第5-7個9取一個 取一個99999
第五次 從第6-8個9 取一個 是 999999
第六次 從第7-9個9 後面仍滿足取一個是 9999999
第七次 第8個開始右側已經不夠三個9了,所有取消匹配,匹配之前的7個9

3、(?<=<(\w+)>).*(?=<\/\1>)

詳細解釋下:?<=和?=都表示零寬斷言,一個匹配後面一個匹配前面,
對應到上面的例子中,亦即.*前面必須要有<(\w+)>,後面必須要有<\/\1>。
零寬斷言不體現到最終的匹配結果中。
再細看下,<(\w+)>匹配<tag>型別,\w表示數字、字母、下劃線;<\/\1>中\/匹配斜槓/,
\1表示捕獲組,亦即從正則表示式左邊開始的第一個小括號中的內容,注意這裡不包含零寬斷言的括號,在上例中表示(\w+)中的部分。
中間的.*表示任意多個非換行符。

總結下:匹配類似<tag>content</tag>格式中的content部分

不過經過測試網頁版的js匹配不到,還是Regex Match Tracer中比較好用,推薦大家下載學習

網頁版看不到效果

超強變態的正則(\w)((?=)())+講解

用軟體就可以

超強變態的正則(\w)((?=)())+講解

所有大家在使用的時候,要測試你的語言是否支援。

正則表示式看懂的最好方法就是一步步分開解析:

1)以 '.*' 為分界,前面括號中的內容可以劃分為 ‘?<=' 和 ‘<(\w+)>',其中‘<(\w+)>'表示匹配尖括號裡面是字母、數字或下劃線的內容,類似<span>,外面還要加個括號是要實現分組;而‘?<='用到的是零寬斷言語法,表示的是斷定‘<(\w+)>'後面有或沒有內容,而且與內容的間隔寬度為零。
2)再看' .* '後面的部分,括號裡面的內容可以分為 ‘?=' 和 ‘<(\/\1>',其中‘?='用零寬斷言表示匹配‘<(\/\1>'前面的部分,而對於‘<(\/\1>',‘\/'匹配‘/'符號,類似</span>,這裡可能有些同學不太明白‘\1'是什麼意思?這裡用到的是捕獲分組的思想,上述提到的‘<(\w+)>'外面加個小括號就表示一個分組,對於正則表示式的分組結果,索引 0表示匹配的整個內容,而1表示的是第1個子分組,所以這裡的'\1'指向的就是前面的第一個分組‘<(\w+)>',\2表示重複第2個子項,\n表示重複第n個子項;
3).* 就比較簡單了,表示的是匹配 除了換行符意外的任意字元0次或多次。
綜上,改表示式匹配的是類似html標籤這種內容的,如<body>你好,正則!</body>

下面是我們小編寫的打算將不帶style的span替換為空的正則。

超強變態的正則(\w)((?=)())+講解

str=str.replace(/<span\s*?(?!:style)>(.[^<>]*)<\/span>/ig,"$1");

不可能用的,要不所有的內容都亂了。

文中相關測試工具

JavaScript正則表示式線上測試工具

Regex Match Tracer

下面接這個為大家分享這幾個高階規則

預搜尋,不匹配;反向預搜尋,不匹配
前面的章節中,我講到了幾個代表抽象意義的特殊符號:"^","$","\b"。它們都有一個共同點,那就是:它們本身不匹配任何字元,只是對 "字串的兩頭" 或者 "字元之間的縫隙" 附加了一個條件。理解到這個概念以後,本節將繼續介紹另外一種對 "兩頭" 或者 "縫隙" 附加條件的,更加靈活的表示方法。

正向預搜尋:"(?=xxxxx)","(?!xxxxx)"

格式:"(?=xxxxx)",在被匹配的字串中,它對所處的 "縫隙" 或者 "兩頭" 附加的條件是:所在縫隙的右側,必須能夠匹配上 xxxxx 這部分的表示式。因為它只是在此作為這個縫隙上附加的條件,所以它並不影響後邊的表示式去真正匹配這個縫隙之後的字元。這就類似 "\b",本身不匹配任何字元。"\b" 只是將所在縫隙之前、之後的字元取來進行了一下判斷,不會影響後邊的表示式來真正的匹配。

點選測試 舉例1:表示式 "Windows (?=NT|XP)" 在匹配 "Windows 98,Windows 2000" 時,將只匹配 "Windows NT" 中的 "Windows ",其他的 "Windows " 字樣則不被匹配。

點選測試 舉例2:表示式 "(\w)((?=\1\1\1)(\1))+" 在匹配字串 "aaa ffffff 999999999" 時,將可以匹配6個"f"的前4個,可以匹配9個"9"的前7個。這個表示式可以讀解成:重複4次以上的字母數字,則匹配其剩下最後2位之前的部分。當然,這個表示式可以不這樣寫,在此的目的是作為演示之用。

格式:"(?!xxxxx)",所在縫隙的右側,必須不能匹配 xxxxx 這部分表示式。

點選測試 舉例3:表示式 "((?!\bstop\b).)+" 在匹配 "fdjka ljfdl stop fjdsla fdj" 時,將從頭一直匹配到 "stop" 之前的位置,如果字串中沒有 "stop",則匹配整個字串。

點選測試 舉例4:表示式 "do(?!\w)" 在匹配字串 "done,do,dog" 時,只能匹配 "do"。在本條舉例中,"do" 後邊使用 "(?!\w)" 和使用 "\b" 效果是一樣的。

反向預搜尋:"(?<=xxxxx)","(?<!xxxxx)"

這兩種格式的概念和正向預搜尋是類似的,反向預搜尋要求的條件是:所在縫隙的 "左側",兩種格式分別要求必須能夠匹配和必須不能夠匹配指定表示式,而不是去判斷右側。與 "正向預搜尋" 一樣的是:它們都是對所在縫隙的一種附加條件,本身都不匹配任何字元。

舉例5:表示式 "(?<=\d{4})\d+(?=\d{4})" 在匹配 "1234567890123456" 時,將匹配除了前4個數字和後4個數字之外的中間8個數字。由於 JScript.RegExp 不支援反向預搜尋,因此,本條舉例不能夠進行演示。很多其他的引擎可以支援反向預搜尋,比如:Java 1.4 以上的 java.util.regex 包,.NET 中System.Text.RegularExpressions 名稱空間,以及本站推薦的最簡單易用的 DEELX 正則引擎。

到此這篇關於超強變態的正則(\w)((?=\1\1\1)(\1))+講解的文章就介紹到這了,更多相關正則表示式高階規則內容請搜素我們以前的文章或下面相關文章,希望大家以後多多支援我們!