正则学习笔记

正则学习笔记

书写规则

参考:https://www.w3school.com.cn/jsref/jsref_obj_regexp.asp

image-20200708184136181

元字符

元字符(Metacharacter)是拥有特殊含义的字符:

元字符 描述
. 查找单个字符,除了换行和行结束符。
\w 查找单词字符。
\W 查找非单词字符。
\d 查找数字。
\D 查找非数字字符。
\s 查找空白字符。
\S 查找非空白字符。
\b 匹配单词边界。
\B 匹配非单词边界。
\0 查找 NUL 字符。
\n 查找换行符。
\f 查找换页符。
\r 查找回车符。
\t 查找制表符。
\v 查找垂直制表符。
\xxx 查找以八进制数 xxx 规定的字符。
\xdd 查找以十六进制数 dd 规定的字符。
\uxxxx 查找以十六进制数 xxxx 规定的 Unicode 字符。

量词

量词 描述
n+ 匹配任何包含至少一个 n 的字符串。
n* 匹配任何包含零个或多个 n 的字符串。
n? 匹配任何包含零个或一个 n 的字符串。
n{X} 匹配包含 X 个 n 的序列的字符串。
n{X,Y} 匹配包含 X 至 Y 个 n 的序列的字符串。
n{X,} 匹配包含至少 X 个 n 的序列的字符串。
n$ 匹配任何结尾为 n 的字符串。
^n 匹配任何开头为 n 的字符串。
?=n 匹配任何其后紧接指定字符串 n 的字符串。
?!n 匹配任何其后没有紧接指定字符串 n 的字符串。

量词的影响范围:量词只能默认影响前面一个字符或一个()中的内容 要影响多个可以配置分组使用

修饰符

修饰符 描述
i 执行对大小写不敏感的匹配。
g 执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。
m 执行多行匹配。

范围匹配

方括号用于查找某个范围内的字符:

表达式 描述
[abc] 查找方括号之间的任何字符。
[^abc] 查找任何不在方括号之间的字符。
[0-9] 查找任何从 0 至 9 的数字。
[a-z] 查找任何从小写 a 到小写 z 的字符。
[A-Z] 查找任何从大写 A 到大写 Z 的字符。
[A-z] 查找任何从大写 A 到小写 z 的字符。
[adgk] 查找给定集合内的任何字符。
[^adgk] 查找给定集合外的任何字符。
(red|blue|green) 查找任何指定的选项。

分组

/([A-z]\d)+/

位置限制

^ $

范围排除

image-20200709190842389

'afcabcaccadc'.match(/a[^bfac]c/g) 表示a c 之间排除bfac
//["adc"]

[ ^ ] ^在中括号开始位置时表示排除[ ] 内的字符 注意:在中间就只代表^符号

多选匹配

/[a-z]|[A-Z]+/g 匹配小写或大写字母
'AFAFsdfDsdfDFASDdsfDSFsdfFD'.match(/[a-z]|[A-Z]+/g)
//["AFAF", "s", "d", "f", "D", "s", "d", "f", "DFASD", "d", "s", "f", "DSF", "s", "d", "f", "FD"]

多选匹配分别配置各自的结果 并都返回

正则方法

1. test 方法

返回 true 或 false 验证字符串中有没有符合要求

/^1[3-9]\d{9}$/.test("12333333"); //验证手机号码 false

2. exec 提取正则中符合要求的值

str的 match 方法相似 只返回第一次配备的结果 并额外返回两个参数

index:当前匹配结果出现的位置

input:匹配的整个字符串本身

RegExp对象属性lastIndex用来标记 exec 方法下次匹配的开始位置

没有全局修饰符 g

lastIndex始终为 0,不会改变

使用全局修饰符 g

每次匹配之后,会将当前匹配结果后面的字符的所在位置作为lastIndex的值

如果匹配不到结果,lastIndex的值将重置为 0,并且返回结果为 null

let str = "afcabcaccadc";
let re = /a[^bac]c/g; //有g的情况
re.lastIndex; //0
re.exec(str); // ["afc", index: 9, input: "afcabcaccadc", groups: undefined]
re.lastIndex; //3
re.exec(str); //["adc", index: 9, input: "afcabcaccadc", groups: undefined]
re.lastIndex; //12
re.exec(str); //null
re.lastIndex; //0
let re1 = /a[^bac]c/; //没有g的情况
re1.lastIndex; //0
re1.exec(str); // ["afc", index: 9, input: "afcabcaccadc", groups: undefined]
re1.lastIndex; //0
re1.exec(str); // ["afc", index: 9, input: "afcabcaccadc", groups: undefined]

字符串方法

方法用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串。
与 indexOf 方法类似,如果没有找到任何匹配的子串,则返回 -1。

2. match

match() 方法可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配。

该方法类似 indexOf() 和 lastIndexOf(),但是它返回指定的值,而不是字符串的位置。

语法

stringObject.match(searchvalue)
stringObject.match(regexp)
参数 描述
searchvalue 必需。规定要检索的字符串值。
regexp 必需。规定要匹配的模式的 RegExp 对象。如果该参数不是 RegExp 对象,则需要首先把它传递给 RegExp 构造函数,将其转换为 RegExp 对象。

返回值

存放匹配结果的数组。该数组的内容依赖于 regexp 是否具有全局标志 g。

说明

match() 方法将检索字符串 stringObject,以找到一个或多个与 regexp 匹配的文本。这个方法的行为在很大程度上有赖于 regexp 是否具有标志 g。

如果 regexp 没有标志 g,那么 match() 方法就只能在 stringObject 中执行一次匹配。如果没有找到任何匹配的文本, match() 将返回 null。否则,它将返回一个数组,其中存放了与它找到的匹配文本有关的信息。该数组的第 0 个元素存放的是匹配文本,而其余的元素存放的是与正则表达式的子表达式匹配的文本。除了这些常规的数组元素之外,返回的数组还含有两个对象属性。index 属性声明的是匹配文本的起始字符在 stringObject 中的位置,input 属性声明的是对 stringObject 的引用。

如果 regexp 具有标志 g,则 match() 方法将执行全局检索,找到 stringObject 中的所有匹配子字符串。若没有找到任何匹配的子串,则返回 null。如果找到了一个或多个匹配子串,则返回一个数组。不过全局匹配返回的数组的内容与前者大不相同,它的数组元素中存放的是 stringObject 中所有的匹配子串,而且也没有 index 属性或 input 属性。

注意:在全局检索模式下,match() 即不提供与子表达式匹配的文本的信息,也不声明每个匹配子串的位置。如果您需要这些全局检索的信息,可以使用 RegExp.exec()。

3. replace

  1. replace stringObject.replace(regexp/substr,replacement) replacement 可以直接写替代字符 也可以时一个函数,函数有四个参数, 函数的第一个参数是匹配到的字符串,如果有分组,接下来的参数就是匹配到的分组。然后是匹配到的字符串的位置,最后是被匹配的字符串。
const name = '"a", "b"';
const fn: any = (a, b, c, d) => {
  console.log("fn:any -> a,b,c,d", a, b, c, d);
  //第一次 fn:any -> a,b,c,d "a" a 0 "a", "b" 第二次fn:any -> a,b,c,d "b" b 5 "a", "b"
  return "'" + b + "'";
};
const a = '"' + name.replace(/"([^"]*)"/g, fn) + '"';
console.log("created -> a", a); //created -> a "'a', 'b'"

replacement 中的 $ 字符具有特定的含义。如下表所示,它说明从模式匹配得到的字符串将用于替换。

字符 替换文本
$1、$2、...、$99 regexp 中的第 1 到第 99 个子表达式相匹配的文本。
$& regexp 相匹配的子串。
$` 位于匹配子串左侧的文本。
$' 位于匹配子串右侧的文本。
$$ 直接量符号。

4. split

split() 方法用于把一个字符串分割成字符串数组。

语法

stringObject.split(separator, howmany);
参数 描述
separator 必需。字符串或正则表达式,从该参数指定的地方分割 stringObject。
howmany 可选。该参数可指定返回的数组的最大长度。如果设置了该参数,返回的子串不会多于这个参数指定的数组。如果没有设置该参数,整个字符串都会被分割,不考虑它的长度。

separator 是包含子表达式的正则表达式,那么返回的数组中包括与这些子表达式匹配的字串(但不包括与整个正则表达式匹配的文本)

单词边界和空白字符

RegExp 对象属性

属性 描述 FF IE
global RegExp 对象是否具有标志 g。 1 4
ignoreCase RegExp 对象是否具有标志 i。 1 4
lastIndex 一个整数,标示开始下一次匹配的字符位置。 1 4
multiline RegExp 对象是否具有标志 m。 1 4
source 正则表达式的源文本。

应用练习

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div class="container"></div>
    <ul>
      <li class="sClass b">1</li>
      <li class="sClass a">2</li>
      <li class="sClass">3</li>
      <li class="sClass w">4</li>
      <li class="sClass">5</li>
      <li class="sClass">6</li>
    </ul>
  </body>
  <script>
    window.onload = function () {
      /**
       * @description: 根据类名获取元素
       * @param {type} sClass 类名
       * @param {type} container  查找范围
       * @return: 查到的元素 没有返回null
       * @author: Seven
       */
      let getByClass = (sClass, container) => {
        let nodes = (container || document).getElementsByTagName("*");

        let node = [].find.call(nodes, function (el) {
          console.dir(el);
          let re = new RegExp(`\\b${sClass}\\b`);
          if (el.className.search(re) != -1) {
            return el;
          }
        });
        return node || null;
      };
      console.log("classnode");
      console.dir(getByClass("sClass"));
      let data = [
        {
          title: "国内专利、商标申请双增长",
          content:
            "国家知识产权局新闻发言人胡文辉介绍,今年上半年,我国国内三种类型专利申请219.5万件、商标申请417万件。国内专利",
        },
        {
          title: "国内专利、商标申请双增长",
          content:
            "国家知识产权局新闻发言人胡文辉介绍,今年上半年,我国国内三种类型专利申请219.5万件、商标申请417万件。国内专利",
        },
        {
          title: "国内专利、商标申请双增长",
          content:
            "国家知识产权局新闻发言人胡文辉介绍,今年上半年,我国国内三种类型专利申请219.5万件、商标申请417万件。国内专利",
        },
        {
          title: "国内专利、商标申请双增长",
          content:
            "国家知识产权局新闻发言人胡文辉介绍,今年上半年,我国国内三种类型专利申请219.5万件、商标申请417万件。国内专利",
        },
      ];

      /**
       * @description: 模板编译方法
       * @param {type} temp 模板dom
       * @param {type} data 模板json
       * @return: 编译好的模板HTML
       * @author: Seven
       */

      let handleTemplate = (temp, datas) => {
        console.log("handleTemplate -> temp", temp);
        console.dir(temp);
        let html = "";
        datas.forEach((data) => {
          let innerHTML = temp.innerHTML;
          for (const key in data) {
            if (data.hasOwnProperty(key)) {
              let reg = new RegExp(`{{${key}}}`);
              innerHTML = innerHTML.replace(reg, data[key]);
            }
          }
          html += innerHTML;
          console.log("handleTemplate -> html", html);
        });

        return html;
      };
      let tempNode = document.getElementById("temp");
      getByClass("container").innerHTML = handleTemplate(tempNode, data);
    };
  </script>

  <script type="text/template" id="temp">
    <h1>{{title}}</h1>
    <p>{{content}}</P>
  </script>
</html>

常用的正则

vscode 匹配对: 后面的字符进行匹配

/:([^]+)$/  //最少一次
/:([^]*)$/  //不限次数
/:([^]?)*/  //后面没有字符的请求
posted @ 2021-10-11 13:34  __Bowen  阅读(55)  评论(0编辑  收藏  举报