W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
選擇是正則表達式中的一個術語,實際上是一個簡單的“或”。
在正則表達式中,它用豎線 |
表示。
例如,我們想要找出編程語言:HTML、PHP、Java 或 JavaScript。
對應的正則表達式為:html|php|java(script)?
。
用例如下:
let regexp = /html|php|css|java(script)?/gi;
let str = "First HTML appeared, then CSS, then JavaScript";
alert( str.match(regexp) ); // 'HTML', 'CSS', 'JavaScript'
我們看到過類似的東西 —— 方括號。它允許我們在多個字符中進行選擇,例如 gr[ae]y
匹配 gray
或 grey
。
方括號只允許字符或字符類。選擇允許任何表達式。正則表達式 A|B|C
表示表達式 A
、B
或 C
其一均可。
例如:
gr(a|e)y
? 等同于 ?gr[ae]y
?。gra|ey
? 表示 ?gra
? 或 ?ey
?。要將選擇應用于模式中一部分內(nèi)容的選擇,我們可以將其括在括號中:
I love HTML|CSS
匹配 I love HTML
或 CSS
。I love (HTML|CSS)
匹配 I love HTML
或 I love CSS
。在之前的章節(jié)中有個任務是構(gòu)建用于查找形如 hh:mm
的時間字符串,例如 12:00
。但是簡單的 \d\d:\d\d
太模糊了。它也會匹配 25:99
(因為 25 和 99 都與模式匹配,但這不是有效的時間)。
如何構(gòu)建更好的模式?
我們可以應用更精細的匹配。首先,對于時間:
0
或 1
,那么下一位數(shù)可以是任何數(shù)值:[01]\d
。2
,那么下一位數(shù)必須是 [0-3]
。我們可以使用選擇在正則表達式中編寫這兩種變體:[01]\d|2[0-3]
。
接下來,分鐘必須為從 00
到 59
的數(shù)。寫成正則表達式即為 [0-5]\d
:第一個數(shù)字 0-5
,然后是任何數(shù)字。
如果我們將小時和分鐘的正則表達式組合在一起,我們會得到:[01]\d|2[0-3]:[0-5]\d
我們差不多完成了,但有一個問題。選擇 |
現(xiàn)在恰好位于 [01]\d
和 2[0-3]:[0-5]\d
之間。
也就是說:它只匹配符號左側(cè)或右側(cè)任一表達式。
[01]\d | 2[0-3]:[0-5]\d
此模式查找 [01]\d
或 2[0-3]:[0-5]\d
。
但這是錯誤的,應該只在正則表達式的“小時”部分使用選擇,以允許 [01]\d
或 2[0-3]
。讓我們通過將“小時”括在括號中來糾正這個問題:([01]\d|2[0-3]):[0-5]\d
最終的解決方案:
let regexp = /([01]\d|2[0-3]):[0-5]\d/g;
alert("00:00 10:10 23:59 25:99 1:2".match(regexp)); // 00:00,10:10,23:59
有很多編程語言,例如 Java、JavaScript、PHP、C 或 C++。
構(gòu)建一個正則表達式,用來匹配字符串 Java JavaScript PHP C++ C
中包含的編程語言:
let regexp = /你的正則表達式/g;
alert("Java JavaScript PHP C++ C".match(regexp)); // Java JavaScript PHP C++ C
首先想到的解法是列出所有編程語言,在它們之間加上 |
符號。
但運行結(jié)果不符合預期:
let regexp = /Java|JavaScript|PHP|C|C\+\+/g;
let str = "Java, JavaScript, PHP, C, C++";
alert( str.match(regexp) ); // Java,Java,PHP,C,C
正則表達式引擎注意查找選擇。也就是說:它先檢查是否存在 Java
,不存在 —— 接著匹配 JavaScript
及其后的字符串。
結(jié)果,JavaScript
永遠匹配不到,因為 Java
先被匹配了。
C
和 C++
同理。
這個問題有兩個解決方式:
JavaScript|Java|C\+\+|C|PHP
?。Java(Script)?|C(\+\+)?|PHP
?。測試一下:
let regexp = /Java(Script)?|C(\+\+)?|PHP/g;
let str = "Java, JavaScript, PHP, C, C++";
alert( str.match(regexp) ); // Java,JavaScript,PHP,C,C++
“bb-tag” 形如 [tag]...[/tag]
,tag
匹配 b
、url
或 quote
中之一。
例如:
[b]text[/b]
[url]http://google.com[/url]
BB-tags 可以嵌套。但標簽不能自嵌套,比如:
可以:
[url] [b]http://google.com[/b] [/url]
[quote] [b]text[/b] [/quote]
不可以:
[b][b]text[/b][/b]
標簽可以包含換行,通常:
[quote]
[b]text[/b]
[/quote]
構(gòu)造一個正則表達式用于查找所有 BB-tags 及其內(nèi)容。
例如:
let regexp = /your regexp/flags;
let str = "..[url]http://google.com[/url]..";
alert( str.match(regexp) ); // [url]http://google.com[/url]
如果標簽嵌套,那么我們需要記錄匹配的外層標簽(如果需要,我們可以繼續(xù)在其內(nèi)容中搜索):
let regexp = /你的正則表達式/flags;
let str = "..[url][b]http://google.com[/b][/url]..";
alert( str.match(regexp) ); // [url][b]http://google.com[/b][/url]
起始標簽是 \[(b|url|quote)\]
。
匹配字符串直到遇到結(jié)束標簽 —— 讓我們使用模式 .*?
和修飾符 s
來匹配包括換行符在內(nèi)的任何字符,然后向結(jié)束標簽添加反向引用。
完整模式為:\[(b|url|quote)\].*?\[/\1]
。
代碼運行如下:
let regexp = /\[(b|url|quote)].*?\[\/\1]/gs;
let str = `
[b]hello![/b]
[quote]
[url]http://google.com[/url]
[/quote]
`;
alert( str.match(regexp) ); // [b]hello![/b],[quote][url]http://google.com[/url][/quote]
請注意,除了轉(zhuǎn)義 [
之外,我們還必須為結(jié)束標簽 [\/\1]
轉(zhuǎn)義一個斜線,因為通常斜線會關閉模式。
構(gòu)建一個正則表達式以查找雙引號 ?"..."
? 中的字符串。
字符串應該支持轉(zhuǎn)義,就像 JavaScript 字符串一樣。例如,引號可以插入為 \"
,換行符可以插入為 \n
,而反斜線本身可以插入為 \\
。
let str = "Just like \"here\".";
請注意,轉(zhuǎn)義的引號 \"
不會結(jié)束字符串匹配。
所以,我們應該匹配兩個引號之間的內(nèi)容,且忽略中間轉(zhuǎn)義的引號。
這是任務的基本部分,否則這個任務就沒什么意思了。
要匹配的字符串示例:
.. "test me" ..
.. "Say \"Hello\"!" ..(其中有被轉(zhuǎn)義的引號)
.. "\\" ..(其中有雙反斜線)
.. "\\ \"" ..(其中有雙反斜線和被轉(zhuǎn)義的引號)
在 JavaScript 中,雙反斜線用于把反斜線轉(zhuǎn)義為字符串,如下所示:
let str = ' .. "test me" .. "Say \\"Hello\\"!" .. "\\\\ \\"" .. ';
// 存儲中的字符串
alert(str); // .. "test me" .. "Say \"Hello\"!" .. "\\ \"" ..
解決方案:/"(\\.|[^"\\])*"/g
。
一步一步來分析一下:
"
\\
,則匹配其后跟隨的任意字符(.)。(技術上,我們必須在模式中用雙反斜線,因為它是一個特殊的字符,但實際上是一個反斜線字符)。[^"\\]
。代碼運行如下:
let regexp = /"(\\.|[^"\\])*"/g;
let str = ' .. "test me" .. "Say \\"Hello\\"!" .. "\\\\ \\"" .. ';
alert( str.match(regexp) ); // "test me","Say \"Hello\"!","\\ \""
寫出一個正則表達式,用于查找 <style...>
標簽。它應該匹配完整的標簽:該標簽可能沒有特性(attributes)<style>
,也可能有很多特性 <style type="..." id="...">
。
……同時正則表達式不應該匹配 <styler>
!
例如:
let regexp = /你的正則表達式/g;
alert( '<style> <styler> <style test="...">'.match(regexp) ); // <style>, <style test="...">
模式的開頭很明顯:<style
。
……但我們不能簡單地將表達式寫為 <style.*?>
,因為會匹配上 <styler>
。
我們要匹配的是在 <style
之后緊跟著一個空格然后是可選的其他內(nèi)容,或者直接是閉標簽 >
。
寫成正則表達式即為:<style(>|\s.*?>)
。
代碼運行如下:
let regexp = /<style(>|\s.*?>)/g;
alert( '<style> <styler> <style test="...">'.match(regexp) ); // <style>, <style test="...">
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: