说说你对正则表达式的理解?

128 阅读3分钟

匹配方法:

正则对象方法:test(), exec() (execute全称)

字符串方法: replace(), match()

      const reg1 = /abc/g

      const res1 = reg1.test('11abcde') //rest()查看是否匹配,返回true/false
      console.log(res1)

      const res2 = reg1.exec('bnabcdefg')  //只会返回第一个匹配的index(数组的形式),没有匹配到返回null
      console.log(res2)  

      const str1 = '学abc,来黑马abc'
      const res3 = str1.replace(reg1,'java')   //replace 敏感词替换
      console.log(res3)

      const str2 = '学abc,来黑马abc'
      const res4 = str2.match(reg1)   // 
      console.log(res4);              // ["abc","abc"]

exec()的输出

image.png replace()第二个参数也可以不写,相当于replace(reg, ‘’)

没有 g- match() 方法会查找 string 中第一个与 regex 匹配的子串。如果找到了匹配项,它会返回一个数组

let text = "The quick brown fox jumps over the lazy dog.";  
let result1 = text.match(/fox/); 
console.log(result1); 
// 输出: ["fox", index: 16, input: "The quick brown fox jumps over the lazy dog.", groups: undefined]

带有 g- match() 方法会查找 string 中所有与 regex 匹配的子串。返回一个数组,其中只包含所有匹配到的字符串本身。

let text = "apple banana apple orange apple";
// 匹配所有 "apple" 
let result2 = text.match(/apple/g); 
console.log(result2); 
// 输出: ["apple", "apple", "apple"]

修饰符:

i:忽视大小写(ignore case)

g:全局匹配,而不是只查找第一个

m: 匹配多行

    // i: 忽视大小写
    const reg = /a/i 
    console.log(reg.test('a'));    //true 
    console.log(reg.test('ABC')); //true

    //g: 全局匹配
    const reg1 = /java/gi
    const str = '学java,找黑马,java好,JAVA6'
    console.log(str.replace(reg1,'前端'))
    
    //m: 多行搜索 (Multiline)
    const text = "Line 1\nLine 2\nLine 3";
    const reg3 = /^Line 1/m; // 匹配 "Line 1"
    console.log(reg3.test(text)); // true

元字符(边界符):

单词边界 \b

匹配cat,遇到wildcat不匹配

// 单词边界 \b
    const text = "The wildcat is a cat."
    // 1. 不使用 \b 的情况 (只匹配 "cat")
    const regex1 = /cat/;
    console.log(text.match(regex1)); // ["cat", index: 8, input: "...", groups: undefined] (只找到第一个 "cat")
    console.log(text.match(/cat/g)); // ["cat", "cat"] (找到所有 "cat",包括 "wildcat" 中的 "cat")

    // 2. 使用 \b 匹配完整的单词 "cat"
    const regex2 = /\bcat\b/g; // /g 标志用于找到所有匹配
    console.log(text.match(regex2)); // ["cat"] (只找到独立的 "cat")

字符串边界 ^ $

// 字符串边界 ^ $
        const reg2 = /^a/        //以...开头
        console.log(reg2.test('aa'))    //true
        console.log(reg2.test('baa'))   //false

        const reg3 = /c$/       //以...结尾
        console.log(reg3.test('abc'))   //true
        console.log(reg3.test('bcd'))   //false

        const reg4 = /^a$/         //要求精确匹配
        console.log(reg4.test('a'))  //true
        console.log(reg4.test('aaa'))//false 

元字符(量词):

  • ✳ 0次或多次
  • 加号(+) 一次或多次
  • ? 0次或1次
  • {n} 只能有n次
  • {n,} 大于等于n次
  • {n,m} n~m次
const reg = /^a*$/

元字符(字符类):

    // [] 中括号里面的任意一个
    const reg = /[abc]/    //abc中的任意一个
    
    const reg1 = /[a-z]/  //a-z 26个字母中任意一个
    const reg2 = /[A-Z]/  //A-Z
    const reg3 = /[0-9]/  //0-9数字中任意一个
    const reg4 = /[a-zA-Z0-9]/

    //[^] 取反 必须在[]内部,没有[]表示以xxx开头 
    const reg5 = /[^abc]/  //匹配abc之外的任意一个

    //.匹配的除换行符之外的任意字符
    const reg6 = /./
    console.log(reg6.test('')) // false
    console.log(reg6.test('\n')) // false
    console.log(reg6.test('\r')) // false
    // \r 将光标移到本行开头 (return)   \n 换行(newline)
    // 经常配合起来使用 windows中 \r\n表示回车并换行。
    
    //预定义
    const reg7 = /\d/ // \d -> [0-9]
    const reg8 = /\D/ // \D -> [^0-9]
    const reg9 = /\w/ // \w -> [a-zA-Z0-9_]  26个英文字母,数字,下划线
    const reg10 = /\W/ // \W -> [^a-zA-Z0-9_]  取反
    const reg11 = /\s/ //匹配空格(包括换行,空格,制表符)  [\t\r\n\v\f]
    const reg12 = /\S/ //取反
    // \d (digit)    \w (word)    \s (whitespace) 
    // \t 水平制表符,用于对齐文本  \v 垂直制表符 

分组和分支结构

    // 分组,括号内的视为整体
    const reg = /(ab)+/   //括号内的可重复
    console.log(reg.test('ababab')) //true
    console.log(reg.test('ababa'))  //false

    const reg2 = /^(\d{4})-(\d{2})-(\d{2})/
    const date = '2023-01-05'
    console.log(reg2.test(date))//true

    const reg3 = /前端|java/   //包含前端或者java都能匹配成功
    const str1 = '前端开始'
    const str2 = 'java炒饭'
    console.log(reg3.test(str1)); 
元字符描述示例
.匹配除换行符 (\n) 以外的任何单个字符。/a.b/ 匹配 "aab", "axb" 但不匹配 "a\nb"
^匹配字符串的开头。/^hello/ 匹配以 "hello" 开头的字符串
$匹配字符串的结尾。/world$/ 匹配以 "world" 结尾的字符串
*匹配前面的元素零次或多次。/ab*/ 匹配 "a", "ab", "abb", "abbb"
+匹配前面的元素一次或多次。/ab+/ 匹配 "ab", "abb", "abbb" 但不匹配 "a"
?匹配前面的元素零次或一次。/ab?/ 匹配 "a", "ab"
{n}匹配前面的元素恰好 n 次。/a{3}/ 匹配 "aaa"
{n,}匹配前面的元素至少 n 次。/a{2,}/ 匹配 "aa", "aaa", "aaaa"
{n,m}匹配前面的元素至少 n 次,至多 m 次。/a{1,3}/ 匹配 "a", "aa", "aaa"
``或(选择器)。匹配 `
()分组。将表达式的一部分视为一个整体,可以用于捕获匹配的子字符串。/(ab)+/ 匹配 "ab", "abab"
[]字符集。匹配方括号内的任意一个字符。/[abc]/ 匹配 "a", "b", "c"
[^]否定字符集。匹配不在方括号内的任意一个字符。/[^abc]/ 匹配除 "a", "b", "c" 以外的字符
\转义字符。用于转义具有特殊含义的元字符,或者匹配字面量的元字符。/./ 匹配字面量的 "."

捕获组

将被分组匹配到的子字符串额外单独提取出来,方便后续分析。 比如:

  • result[0]:整个匹配内容("123-456")
  • result[1]:第一个捕获组内容("123")
  • result[2]:第二个捕获组内容("456")
const regex = /(\d+)-(\d+)/;
const str = "123-456";
const result = str.match(regex);

console.log(result);
// 输出:["123-456", "123", "456"]

参考 面试官:说说你对正则表达式的理解?应用场景? | web前端面试 - 面试官系列