美文网首页
正则表达式 初学篇

正则表达式 初学篇

作者: 幻之国2012 | 来源:发表于2020-05-30 14:29 被阅读0次

    正则表达式 初学篇

    正则表达式 虽说不常用, 但是每当用到的时候基本都要去问百度, 得到的答案可能又不完全适用, 想自己改, 单独看每个字符都很熟悉, 但是连在一起看, (。>д<)p 这都是神马鬼~

    所以是时候学习了解下了, 当你用一行正则表达式完美解决几个嵌套判断才能实现的功能时, 它不香吗?

    举个简单常见的 🌰 :【手机号 验证】

    enmm... 非正则的方法 可能是

      const telNum = '13012341234'
      const telAry = telNum.split('')
      const val1 = telAry.length === 11 ? true : false
      const val2 = telAry[0] === '1' ? true : false
      const val3 = ['3','4','5','7','8'].indexOf(telAry[1]) !== -1 ? true : false
      const result = (val1 && val2 && val3) ? '手机号格式正确' : '手机号格式错误'
    

    那么 正则的方法: /^1[34578][0-9]{9}$/

      const telNum = '13012341234'
      const regex = /^1[34578][0-9]{9}$/
      const result = regex.test(telNum) ? '手机号格式正确' : '手机号格式错误'
    

    然后我们简单分析下 regex, 可以分成下面几个小块

    ^1      //  ^: 表示需要匹配的字符串的开始位置; ^1 表示字符串以1开始
    [34578] // []: 标记一个表达式的开始 [ 与 结束 ]; 此处可以理解为 (3 || 4 || 5 || 7 || 8)
    [0-9]   //     同上; 此处可以理解为 (0 || 1 || 2 ... || 8 || 9)
    {9}     // {}: 限定符, 匹配它前面的表达式出现的次数; 例如: [1]{3} => [1][1][1]
    $       //  $: 表示需要匹配的字符串结束位置; 9$/ 表示需要匹配以 9 结尾的字符串
    

    这时候有的童鞋可能会问, 这个 ^ 怎么读啊? (;¬_¬) 呵呵~, 别问, 问就是我也不知道~
    所以去查了下, 百度百科给的说法是 ^ : 中文尚无通用名称,可以是乘方、插入符号、插入符、脱字符号等;英文称为caret (英语发音:/ˈkærət/); 不过这些不是重点, 只要知道它是干什么用的就好了

    非常简单的小小练习题 1:
    (单选)下面哪个正则表达式可以完全匹配字符串 str='11223 11222 11233 11232'
    A: /^11[23]{3}/g
    B: /[11]{1}[23]{3}/g
    C: /1{2}[23]{3}$/g
    D: /[123]{5}/g
    小拓展: /g => g:表示全局查找, 匹配尽可能多的数据, 如果没有 g ,只匹配第一个符合要求的值

      var str='11223 11222 11233 11232'
      var reg = ''
      console.log(str.match(reg));
    

    常用元字符 及 基本用法

    元字符是构造正则表达式的一种基本元素。

    接下来介绍下正则表达式的常用元字符以及基本用法, 其实网上随随便便就能查到, 但是很多都把它们列在了一起, 乍一看很多的样子, 这里把一些常用的区分开了, 可能会好记一些(对我而言)

    定位符:   ^   $   \b   \B

    定位符 表示你能够将正则表达式固定到行首或行尾

    ^  匹配输入字符串的开始位置; 当该符号在 [] 方括号表达式中使用时, 表示不接受该方括号表达式中的字符集合

      const str = 'the boy is ten years old'
      const reg1 = /^the/g  // 匹配输出 ["The"]
      const reg2 = /^boy/g  // 匹配输出 null
      const reg3 = /[^oes]/g// 匹配输出 ["T", "h", " ", "b", "y", " ", "i", " ", "t", "n", " ", "y", "a", "r", " ", "l", "d"]
    

    $  匹配输入字符串的结尾位置

      const str = 'The boy is ten years old'
      const reg1 = /old$/g  // 匹配输出 ["old"]
      const reg2 = /years$/g// 匹配输出 null
    

    \b  匹配一个单词边界, 即字与空格间的位置

      const str = 'this is sister island persist consist his axis'
      const reg1 = /\w*is\b/g // 匹配输出 ["this", "is", "his", "axis"]
      const reg2 = /\bis\w*/g // 匹配输出 ["is", "island"]
      const reg3 = /\bis\b/g  // 匹配输出 ["is"]
      const reg4 = /\w*is\w*/g// 可以匹配到全部字符
      这里的 \w 与 * 后面会有相关介绍, 这里使用是为了能更好的说明 \b 用法
      // \w: 匹配包括下划线的任何单词字符
      // * : 限定符, 匹配其前面的子表达式出现 0次 或 多次
    

    \B  非单词边界匹配

      const str = 'this is sister island persist consist his axis'
      const reg1 = /\Bis\B/g  //输出 this is sISter island persISt consISt his axis
      const reg2 = /\Bis/g    //输出 thIS is sISter island persISt consISt hIS axIS
      const reg3 = /is\B/g    //输出 this is sISter ISland persISt consISt his axis
      console.log(str.replace(reg1, 'IS')); // 将全部符合要求的 is 替换为 IS
    

    限定符:   *   +   ?   {n}   {n,}   {n,m}

    限定符用来指定它之前的子表达式出现的次数, 目前共有6种

    * 匹配其前面的子表达式出现   0次   或   多次

      const str = 'ABC AAB AAA BBB ABB BAA CCC ACC'
      const reg1 = /AB*/g // 匹配  1个A 0个或多个B 的字符串
      //输出 ["AB", "A", "AB", "A", "A", "A", "ABB", "A", "A", "A"]
    

    + 匹配其前面的子表达式出现   1次   或   多次

      const str = 'ABC AAB AAA BBB ABB BAA CCC ACC'
      const reg1 = /AB+/g // 匹配 1个A 1个或多个B 的字符串
      //输出 ["AB", "AB", "ABB"]
    

    ? 匹配其前面的子表达式出现 0次 或 1次

      const str = 'ABC AAB AAA BBB ABB BAA CCC ACC'
      const reg1 = /AB?/g // 匹配 1个A 0个或1个B 的字符串
      //输出 ["AB", "A", "AB", "A", "A", "A", "AB", "A", "A", "A"]
    

    {n} 匹配其前面的子表达式出现 n次, n 非负整数;

      const str = 'ABC AAB AAA BBB ABB BAA CCC ACC'
      const reg1 = /AB{2}/g // 匹配 1个A 2个B 的字符串
      //输出 ["ABB"]
    

    {n,} 匹配其前面的子表达式至少出现 n次; n 非负整数;

      AB{0,} = AB*
      AB{1,} = AB+
    

    {n,m} 匹配其前面的子表达式至少出现 n 次,最多出现 m 次; n & m 非负整数; {n,m} 之间不能有空格;

      AB{0,1} = AB?
      // {n,m} 之间不能有空格  {0, 1}=>❌   { 0,1 }=>❌
    

    【注】:不能将限定符与定位符连接使用, 错误示例:  ^*   \b*

    其他特殊字符:

    . 匹配除换行符   \n   之外的任何 单字符

    \ 转义特殊字符; 例:  \&nbsp;匹配字符 &nbsp;

    | 指明两项之间的一个选择

      const str = 'AAAAA ABACB ABACA ABBAA ACACA ACBEA ADABC'
      const reg1 = /A(A|B|C)\w{3}/g  // 匹配 AA*** 或者 AB*** 或者 AC*** 形式的字符串
      // ["AAAAA", "ABACB", "ABACA", "ABBAA", "ACACA", "ACBEA"]
      const reg2 = /A(C|BA)\w*/g  // 匹配 AC 开头 或者 ABA 开头 形式的字符串
      // ["ABACB", "ABACA", "ACACA", "ACBEA"]
      const reg3 = /\b(AA\w*|AC\w*)/g  // 匹配 AA*** 或者 AC*** 形式的字符串
      // ["AAAAA", "ACACA", "ACBEA"]
      //  如果去掉 \b 匹配结果为: ["AAAAA", "ACB", "ACA", "AA", "ACACA", "ACBEA"]
      在书写正则表达式的时候, 一定要严格判断, 防止修改到自己预期之外的字符数据
    

    () 标记一个子表达式的开始和结束位置

      const str = 'AAAAA ABACB ABACA ABBAA ACACA ACBEA'
      const reg1 = /A(A|B)A(C|E)\w*/g
      // 匹配 以A开始, 第2个字符是 A 或者 B, 第3个字符是 A, 第4个字符是 C 或者 E 的字符
      // ["ABACB", "ABACA"]
    

    [] 标记一个中括号表达式的开始和结束位置; [] 内的每一个字符 (连字符 - 与 ^ 除外) 都会当做参数做判断

      const str = 'AAA Abc ABB A-C A^B ACT AZZ A=T A5K'
      const reg1 = /A[AB]\w*/g
      // 匹配 AA* 或者 AB* 形式的字符串; [AB] = (A|B)
      // 输出 ["AAA", "ABB"]
      const reg2 = /A[A-D0-9]\w*/g
      // 匹配 A(A|B|C|D)* 或 A(0 到 9 的数字)* 形式的字符串
      // 输出 ["AAA", "ABB", "ACT", "A5K"]
      const reg3 = /A[A--D]\w*/g
      // ❌这是一个错误的表达式;
      const reg4 = /A[-a-z]\w*/g
      // 连字符 出现在两个字符之间时,才能表示字符的范围; 如果出字符组的开头或者结尾,则只能表示连字符本身
      // ["Abc", "A-C"]
      const reg5 = /A[^^A-F]\w*/g
      // ^ 出现在 [] 的开始位置, 表示匹配任何不在指定范围内的任意字符, 出现在其他位置匹配其本身
      // ["A Abc", "A-C", "AZZ", "A=T", "A5K"], 如果不想匹配 "A Abc" 这样的数据需要怎么修改? (提问 1)
    

    {} 标记限定符表达式的开始和结束位置

      const reg1 = /AB{2}/g // 匹配 ABB 字符
      const reg2 = /(AB){2}/g // 匹配 ABAB 字符
      {} 的使用格式只有三种 {n} {n,} {n,m}
    

    \d  匹配一个数字字符。等价于[0-9]

    \D  匹配一个非数字字符。等价于[^0-9]

    \w  匹配包括下划线的任何单词字符, 类似但不等价于“[A-Za-z0-9_]”,这里的"单词"字符使用Unicode字符集。

      const str = 'Ab 你好 #@_(*&^!~10/;⊙'
      const reg1 = /\w/g
      // 输出 ["A", "b", "_", "1", "0"]
    

    \W  匹配任何非单词字符。等价于“[^A-Za-z0-9_]”。

      const str = 'Ab 你好 #@_(*&^!~10/;⊙'
      const reg1 = /\W/g
      // [" ", "你", "好", " ", "#", "@", "(", "*", "&", "^", "!", "~", "/", ";", "⊙"]
    

    \s  匹配任何不可见字符,包括空格、制表符、换页符等等。等价于[ \f\n\r\t\v]

    \S  匹配任何可见字符。等价于[^ \f\n\r\t\v]。

    \f  匹配一个换页符。等价于\x0c和\cL。

    \n  匹配一个换行符。等价于\x0a和\cJ。

    \r  匹配一个回车符。等价于\x0d和\cM。

    正则表达式模式修饰符

    /g 全局标记, 表示该表达式将用来在输入字符串中查找所有可能的匹配,返回的结果可以是多个。如果不加/g最多只会匹配一个

      const str = 'the girl, the boy'
      const reg1 = /the/  // 只能匹配到 第一个 the
      const reg2 = /the/g // 可以匹配到全部 the
    

    /i  表示匹配的时候不区分大小写

     const str='IS is Is iS'
     const reg1 = /is/g  // 只能匹配到 is
     const reg2 = /is/gi // 可以匹配到全部 全局匹配不区分大小写
    

    /m  表示多行匹配。什么是多行匹配呢?就是匹配换行符两端的潜在匹配。影响正则中的^$符号

    /s  与/m相对,单行模式匹配。

    /e  可执行模式,此为PHP专有参数,例如preg_replace函数。

    /x  忽略空白模式。

    简单的小小练习题 2:
    (单选)能够完全匹配字符串 "(010)-62661617" 和字符串 "010****8099"的正则表达式是
    A: /(?\d{3})?-?\d{8}/g
    B: /[0-9(-)]\d/g
    C: /[0-9*()-]+/g
    D: /[(]?\d[)-]\d*/g

    到这里的时候, 你应该就可以写一些简单的正则用来判断处理字符串了,
    然后有的童鞋可能还会问, 如果想修改别人的正则表达式从何下手?或者说看到一个很长很长的正则怎么去理解什么意思?

    例如: /[1-8]\d{5}((18|19|20))?\d{2}[0-1]\d[0-3]\d{4}(\d|x)?/

    其实从左到右分块按顺序转义就好了

      [1-8]   // 一个 1-8 的数字
      \d{5}   // 5 个 0-9 的数字
      ((18|19|20))? // 无 或者 18 或者 19 或者 20
      \d{2}   // 2 个 0-9 的数字
      [0-1]   // 0 或者 1
      \d      // 一个 0-9 的数字
      [0-3]   // 0 或者 1 或者 2 或者 3
      \d{4}   // 4 个 0-9 的数字
      (\d|x)? // 无 或者 1个0-9的数字 或者 X
    

    正则表达式 的运算符优先级

    运算符优先级: 高 --> 低

    \  转义符 最高

    (),(?:),(?=),[]  圆括号 方括号

    *,+,?,{n},{n,},{n,m}  限定符

    ^,$,\任何字符  定位点和序列

    |  或者

    正则初学篇 就到此结束吧!

    非常感谢大家百忙之中看完本片文档, 如果哪里有错误的地方请大家指出, 如果哪里说得不好不够详细的, 请大家多做自我批评~

    如果后期有机会 可能会在深入学习下, 也会对此篇进行完善, 毕竟还有很多正则知识在这里没有介绍到;
    (*^_^*) 再次感谢! 有缘再见~


    简单的小小练习题答案:
    题1: D
    题2: C

    提问 答案:
    1: /\bA[^^A-F]\w*/g

    工具推荐

    在线工具(菜鸟在线工具,可以编译正则表达式,并查看匹配结果,还给出了一些常用的表达式写法)

    REGEXPER(一个让正则表达式图形化的工具, 据说转义图形后更加简单易懂)

    正则元字符列表

    相关文章

      网友评论

          本文标题:正则表达式 初学篇

          本文链接:https://www.haomeiwen.com/subject/thxbmqtx.html