正則表達式里問號?的用法


文章原文:https://www.cnblogs.com/yalong/p/15183458.html

1.普通的問號符號

因為 ? 是特殊符號,所以如果想把 ? 當做正常的問號匹配,就需要加轉義 \?

示例
var regex = /123\?456/
var str = '123?456'
regex.test(str)  // true

2.量詞

問號可以表示重復前面內容的0次或一次,也就是要么不出現,要么出現一次

示例
var regex = /1?23/
regex.test('123') // true
regex.test('1123') // true
regex.test('1234') // true
regex.test('121') // false

3.惰性模式匹配

量詞模式是貪婪模式,在量詞后面加上問號,就變成了惰性匹配
看如下量詞的表格

模式 說明
{n,m} 連續出現 n 到 m 次。貪婪模式
{n,} 至少連續出現 n 次。貪婪模式
{n} 連續出現 n 次。貪婪模式
? 等價於 {0,1}。貪婪模式
+ 等價於 {1,}。貪婪模式
* 等價於 {0,}。貪婪模式
量詞后面加上問號后如下
模式 說明
---- ----
{n,m}? 連續出現 n 到 m 次。惰性模式
{n,}? 至少連續出現 n 次。惰性模式
{n}? 連續出現 n 次。惰性模式
?? 等價於 {0,1}?。惰性模式
+? 等價於 {1,}?。惰性模式
*? 等價於 {0,}?。惰性模式
貪婪模式 跟 惰性模式的區別
  1. 貪婪匹配是先看整個字符串是否匹配,如果不匹配,它會去掉字符串的最后一個字符,並再次嘗試,如果還不匹配,那么再去掉當前最后一個,直到發現匹配或不剩任何字符。
  2. 惰性匹配是從左側第一個字符開始向右匹配, 先看第一個字符是不是一個匹配, 如果不匹配就加入下一個字符再嘗式匹配, 直到發現匹配

4.非捕獲性分組

  1. 正常只使用括號就是捕獲模式,可以捕獲括號里的數據,保存在內存中,所以捕獲模式會占用更多內存
  2. 非捕獲模式,就是在里面的最前面加?:
示例

RegExp 會保存分組里的數據, 如下所示

var regex = /(\d{4})-(\d{2})-(\d{2})/
regex.test('2011-11-12') // true
RegExp.$1 // "2011"
RegExp.$2 // "11"
RegExp.$3 // "12"

使用?:的分組就是非捕獲模式,RegExp 不會保存該分組的數據,如下所示

var regex = /(?:\d{4})-(\d{2})-(?:\d{2})/
regex.test('2011-11-12') // true
RegExp.$1 // "11"
RegExp.$2 // ""

5.斷言

1.正先行斷言(前瞻)

(?=X)

2.負先行斷言(前瞻)

(?!X)

3.正后發斷言(后顧)

(?<=X)

4.負后發斷言(后顧)

(?<!X)

語法 說明
(?=X ) 正先行斷言。僅當子表達式 X 在 此位置的右側匹配時才繼續匹配。例如,/w+(?=/d) 與后跟數字的單詞匹配,而不與該數字匹配。此構造不會回溯
(?!X) 負先行斷言。僅當子表達式 X 不在 此位置的右側匹配時才繼續匹配。例如,例如,/w+(?!/d) 與后不跟數字的單詞匹配,而不與該數字匹配
(?<=X) 正后發斷言。僅當子表達式 X 在 此位置的左側匹配時才繼續匹配。例如,(?<=19)99 與跟在 19 后面的 99 的實例匹配。此構造不會回溯
(?<!X) 負后發斷言。僅當子表達式 X 不在此位置的左側匹配時才繼續匹配。例如,(?<!19)99 與不跟在 19 后面的 99 的實例匹配
簡單來說,前瞻就是 看后面等於(?=), 后面不等於 (?!), 后顧就是 前面等於 (?<=), 前面不等於 (?<!)

比如 (?<!AA)eat(?=milk) 表示, eat 前面不能是AA, 后面必須是 milk

比如 (?<=AA)eat(?!milk) 表示 eat 前面必須是AA, 后面不能是milk

示例
  let str1 = "VVeatmilk"
  let str2 = "AAeatfood"
  let patt1 = new RegExp("(?<!AA)eat(?=milk)");
  let patt2 = new RegExp("(?<=AA)eat(?!milk)");
  let result1 = patt1.test(str1);
  let result2 = patt2.test(str2);
  console.log(result1) // true
  console.log(result2) // true
以(?=p) 和 (?!p)為例

(?=p),其中 p 是一個子模式,即 p 前面的位置,或者說,該位置后面的字符要匹配 p
比如 (?=l),表示 l 字符前面的位置,例如:

var result = "hello".replace(/(?=l)/g, '#');
console.log(result);
// => "he#l#lo"

而 (?!p) 就是 (?=p) 的反面意思,比如:

 var result = "hello".replace(/(?!l)/g, '#');
 console.log(result);
 // => "#h#ell#o#"

(?<=p)(?<!p) 同理


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM