Javascript 模式(Patterns)和修飾符(flags)

2023-02-17 10:59 更新

正則表達(dá)式是提供了一種在文本中進(jìn)行搜索和替換的強(qiáng)大的方式的模式。

在 JavaScript 中,我們可以通過 RegExp 對象使用它們,也可以與字符串方法結(jié)合使用。

正則表達(dá)式

正則表達(dá)式(可叫作 “regexp”,或 “reg”)包擴(kuò) 模式 和可選的 修飾符。

有兩種創(chuàng)建正則表達(dá)式對象的語法。

較長一點(diǎn)的語法:

regexp = new RegExp("pattern", "flags");

較短一點(diǎn)的語法,使用斜線 "/"

regexp = /pattern/; // 沒有修飾符
regexp = /pattern/gmi; // 帶有修飾符 g、m 和 i(后面會講到)

斜線 /.../ 告訴 JavaScript 我們正在創(chuàng)建一個正則表達(dá)式。它的作用與字符串引號的作用相同。

在這兩種情況下,regexp 都會成為內(nèi)建類 RegExp 的一個實(shí)例。

這兩種語法之間的主要區(qū)別在于,使用斜線 /.../ 的模式不允許插入表達(dá)式(如帶有 ${...} 的字符串模板)。它是完全靜態(tài)的。

在我們寫代碼時就知道正則表達(dá)式時則會使用斜線的方式 —— 這是最常見的情況。當(dāng)我們需要從動態(tài)生成的字符串“動態(tài)”創(chuàng)建正則表達(dá)式時,更經(jīng)常使用 new RegExp。例如:

let tag = prompt("What tag do you want to find?", "h2");
?
let regexp = new RegExp(`<${tag}>`); // 如果在上方輸入到 prompt 中的答案是 "h2",則與 /<h2>/ 相同

修飾符

正則表達(dá)式可能會有的會影響搜索結(jié)果的修飾符。

在 JavaScript 中,有 6 個修飾符:

?i ?

使用此修飾符后,搜索時不區(qū)分大小寫:?A? 和 ?a? 之間沒有區(qū)別(請參見下面的示例)。

?g ?

使用此修飾符后,搜索時會尋找所有的匹配項 —— 沒有它,則僅返回第一個匹配項。

?m ?

多行模式(詳見 錨點(diǎn) ^ $ 的多行模式,修飾符 "m")。

?s ?

啟用 “dotall” 模式,允許點(diǎn) . 匹配換行符 \n(在 字符類 中有詳細(xì)介紹)。

?u ?

開啟完整的 Unicode 支持。該修飾符能夠正確處理代理對。詳見 Unicode:修飾符 "u" 和類 \p{...}。

?y ?

粘滯模式,在文本中的確切位置搜索(詳見 粘性修飾符 "y",在位置處搜索

顏色

接下來,各部分的顏色如下:?

  • 正則表達(dá)式 —— ?red?
  • 字符串(我們搜索的地方)—— ?blue?
  • 結(jié)果 —— ?green?

搜索:str.match

正如前面所提到的,將正則表達(dá)式和字符串方法結(jié)合一起使用。

str.match(regexp) 方法在字符串 str 中尋找 regexp 的所有匹配項。

它有 3 種工作模式:

  1. 如果正則表達(dá)式具有修飾符 g,它返回一個由所有匹配項所構(gòu)成的數(shù)組:
  2. let str = "We will, we will rock you";
    
    alert( str.match(/we/gi) ); // We,we(由兩個匹配的子字符串構(gòu)成的數(shù)組)

    請注意,We 和 we 都被找到了,因?yàn)樾揎椃?nbsp;i 使得正則表達(dá)式在進(jìn)行搜索時不區(qū)分大小寫。

  3. 如果沒有這樣的修飾符,它則會以數(shù)組形式返回第一個匹配項,索引 0 處保存著完整的匹配項,返回的結(jié)果的屬性中還有一些其他詳細(xì)信息:
  4. let str = "We will, we will rock you";
    
    let result = str.match(/we/i); // 沒有修飾符 g
    
    alert( result[0] );     // We(第一個匹配項)
    alert( result.length ); // 1
    
    // 詳細(xì)信息:
    alert( result.index );  // 0(匹配項的位置)
    alert( result.input );  // We will, we will rock you(源字符串)

    如果正則表達(dá)式中有一部分內(nèi)容被包在括號里,那么返回的數(shù)組可能會有 0 以外的索引。我們將在 捕獲組 中學(xué)習(xí)這部分相關(guān)內(nèi)容。

  5. 最后,如果沒有匹配項,則返回 null(無論是否有修飾符 g)。
  6. 這是一個非常重要的細(xì)微差別。如果沒有匹配項,我們不會收到一個空數(shù)組,而是會收到 null。忘了這一點(diǎn)可能會導(dǎo)致錯誤,例如:

    let matches = "JavaScript".match(/HTML/); // = null
    
    if (!matches.length) { // Error: Cannot read property 'length' of null
      alert("Error in the line above");
    }

    如果我們希望結(jié)果始終是一個數(shù)組,我們可以這樣寫:

    let matches = "JavaScript".match(/HTML/) || [];
    
    if (!matches.length) {
      alert("No matches"); // 現(xiàn)在可以了
    }

替換:str.replace

str.replace(regexp, replacement) 方法使用 replacement 替換在字符串 str 中找到的 regexp 的匹配項(如果帶有修飾符 g 則替換所有匹配項,否則只替換第一個)。

例如:

// 沒有修飾符 g
alert( "We will, we will".replace(/we/i, "I") ); // I will, we will

// 帶有修飾符 g
alert( "We will, we will".replace(/we/ig, "I") ); // I will, I will

第二個參數(shù)是字符串 replacement。我們可以在其中使用特殊的字符組合來對匹配項進(jìn)行插入:

符號 在替換字符串中的行為
$& 插入整個匹配項
$` 插入字符串中匹配項之前的字符串部分
$' 插入字符串中匹配項之后的字符串部分
$n 如果 n 是一個 1-2 位的數(shù)字,則插入第 n 個分組的內(nèi)容,詳見 捕獲組
$<name> 插入帶有給定 name 的括號內(nèi)的內(nèi)容,詳見 捕獲組
$$ 插入字符 $

帶有 $& 的一個示例:

alert( "I love HTML".replace(/HTML/, "{#content}amp; and JavaScript") ); // I love HTML and JavaScript

測試:regexp.test

regexp.test(str) 方法尋找至少一個匹配項,如果找到了,則返回 true,否則返回 false。

let str = "I love JavaScript";
let regexp = /LOVE/i;

alert( regexp.test(str) ); // true

在后面的章節(jié)中,我們會學(xué)習(xí)更多正則表達(dá)式,通過更多的例子,也會遇到其他的方法。

關(guān)于這些方法的完整信息請見 正則表達(dá)式和字符串的方法。

總結(jié)

  • 正則表達(dá)式由模式和可選擇修飾符構(gòu)成:g、im、usy。
  • 沒有修飾符和特殊符號(稍后我們會學(xué)到),那么正則表達(dá)式的搜索和子字符串的搜索相同。
  • str.match(regexp) 方法尋找匹配項:如果帶有修飾符 g,則會返回所有匹配項,否則只會返回第一個匹配項。
  • str.replace(regexp, replacement) 方法使用 replacement 替換 regexp 的匹配項:如果帶有修飾符 g,則會替換所有匹配項,否則只會替換第一個匹配項。
  • regexp.test(str) 方法用于測試,如果找到至少一個匹配項則返回 true,否則返回 false


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號