js正则表达式--个人学习笔记

185 阅读12分钟

0 学习

下面大部分案例学习自B站up主-后盾人。

1 字面量创建正则表达式

1.1 字面量的使用

要创建正则表达式,可以使用字面量表示法。在JavaScript中,正则表达式字面量使用斜杠(/)包围,例如:

let regEx = /pattern/;

其中,/ / 里是正则表达式的规则模式,用于匹配文本中的特定规则。

例如,要创建一个匹配数字的正则表达式,可以使用以下代码:

let regEx = /\d+/;

这个正则表达式可以匹配一个或多个连续的数字。

字面量创建的正则表达式常常与字符串的testmatch方法一起使用,用于测试字符串是否匹配该正则表达式。

let str = "123abc";
let isMatch = /\d+/.test(str); // true

这个例子中,test方法用于测试字符串 str 是否包含一个或多个数字。由于 str 包含数字,所以 isMatch 变量的值为 true


1.2 在字面量正则中使用变量

字面量正则中不能直接使用变量,只能使用字面量的匹配规则如下

let str = "123abc";
let d = 'b';

let pattern =/123/
let isMatch = pattern.test(str); // true

let isMatch = /d/.test(str); // false,d仍当着字面量d使用,而不是变量b

如果想使用变量,需要借助eval()函数。这个函数可以用来动态生成正则表达式。eval()函数将传入的字符串作为JavaScript代码进行解析和执行,可以求得一个正则对象。

下面是一个使用eval()函数生成正则表达式的例子:

let str = "123abc";
let d = 'b';
let pattern = eval(` /${d}/`);
let isMatch = pattern.test(str); // true


// let isMatch =eval(` /${d}/`).test(str);
//也是一样



在上面的例子中,eval()函数被用来生成一个匹配数字的正则表达式对象。通过调用test()方法,我们可以检查一个字符串是否匹配该正则表达式。

需要注意的是,eval()函数有一些安全问题,尤其是当参数是来自用户输入时。不当的使用eval()函数可能导致代码注入攻击。因此,在使用eval()函数时,一定要谨慎并确保参数的来源可信。


2 使用对象方式创建正则

2.1 创建正则对象

在JavaScript中,可以使用对象方式创建正则表达式。可以通过RegExp对象来创建一个正则表达式。 在创建正则表达式时,需要传递两个参数给RegExp对象。第一个参数是正则表达式的模式,用于指定匹配的规则。第二个参数是可选的标志,用于指定匹配的方式,比如'i'表示忽略大小写,'g'表示全局匹配等。

// 使用对象方式创建正则表达式规则
var regex = new RegExp('hello', 'i');

上述代码创建了一个正则表达式,用于匹配字符串中的"hello",并且忽略大小写。


2.2 动态创建正则

// 使用对象方式创建正则表达式是可以动态的使用变量的
var a = 'hello';
var regex = new RegExp(a, 'i');

使用字面量方式创建正则表达式更简洁,但无法动态指定正则表达式的模式和标志。如果需要动态创建正则表达式,则需要使用对象方式。


2.3 案例实践

<!DOCTYPE html>
<html>

<head>
    <title>Document</title>
</head>

<body>
    <div id="content">houdunren.com</div>
</body>
<script>
    const content = prompt("请输入要搜索的内容,支持正则表达式");
    let body = document.querySelector("#content");
    
    const reg = new RegExp(content, "g");//这只是建立匹配规则
    document.body.innerHTML = body.innerHTML.replace(reg, (str) => {
    //str即为匹配上的字符
        return `<span style="color:red">${str}</span>`;
    });
</script>

</html>

3 原子表和原子组

3.1 选择符

| 这个符号是选择修释符,也就是 | 左右两侧有一个匹配到就可以。在原子组中表示或则的含义

let tel = "010-12345678";
//错误结果:只匹配 | 左右两边任一结果,及010或020\-\d{7,8}
console.log(tel.match(/010|020\-\d{7,8}/));

//正确结果:
console.log(tel.match(/010\-\d{7,8}|020\-\d{7,8}/));

//标准结果:所以需要放在原子组中使用,匹配规则默认是最大的原子组,这概念后面在理解
console.log(tel.match(/(010|020)\-\d{7,8}/));
//返回数组["020-12345678","020"]

匹配字符是否包含abc或 123

const str = "abcdzfjhij";
console.log(/abc|123/.test(str)); //true

3.2 连续符

-在原子表中表示连续的含义,[a-z]表示a到z, [0-9]表示0到9,顺序必须为升序,否则报错


3.3 排除符

^在原子表中表示排除的含义,[^abc]:匹配除了字符集合中的abc以外的任意一个字符。和非的含义类似


3.3 原子表

原子表 [ ] 的含义就是其中任一字符,和选择符含义类似

[abc]:匹配字符集合中的任意一个字符,例如 [abc] 匹配'a'、'b'、'c'中的任意一个字符。

[0-9]:匹配数字字符,相当于 \d。

[a-z]:匹配小写字母。

[^abc]:匹配除了字符集合中的字符以外的任意一个字符。


3.4 原子组

在JavaScript中,正则表达式的原子组是由括号 () 包围的子表达式。原子组可以用来将一部分正则表达式进行分组,以便在表达式中进行引用、重复和捕获。以下是一些常见的正则原子组的示例:

  1. 捕获组:

    • (abc): 匹配字符串 "abc" 并将其捕获到分组中。
    • (?:abc): 匹配字符串 "abc" 但不进行捕获。
  2. 反向引用:

    • (abc) \1: 匹配字符串 "abcabc",其中 \1 表示引用第一个捕获组中的内容。
  3. 零宽断言:

    • (?=abc): 匹配在值后面是 "abc"的值 。
    • (?!abc): 匹配在值后面不是 "abc" 的值。
  4. 非捕获组:

    • (?:abc): 匹配字符串 "abc" 但不进行捕获。
  5. 分组命名:

    • (?<name>abc): 将捕获的内容命名为 "name",可用于后续引用。通过$<name>引用
  6. 原子组嵌套原子表

  • ([(ab)(cd)])表示ab或cd

4 正则中的转义字符

4.1 匹配范围

\d 表示匹配任何一个数字字符 \D 表示匹配一个非数字字符

let str= "abcd 2010";
console.log(str.match(/\d/g)); //["2", "0", "1", "0"]

\w 表示匹配任何一个字母数字字符,字母,数字,下划线 \W 表示匹配一个非字母数字下划线的字符,

let str= "abc_1@";
console.log(str.match(/\w/g)); //["a", "b", "c", "_", "1"]

\s 表示匹配任何一个空白字符, \S 表示匹配一个非空白字符,数字,字母,符号都行

console.log(/\s/.test(" ")); //true
console.log(/\s/.test("\n")); //true

\f 表示匹配一个换页符。 \n 表示匹配一个换行符。 \r 表示匹配一个回车符。

\t 表示匹配一个制表符。 \w 表示匹配一个垂直制表符。

. 表示除换行之外的任意字符 \.表示一个普通的点

类似[\s\S]代表匹配全部

类型分类

  1. 单词 1 数字 2 字母 3 下划线
  2. 空白符 1空格,制表符等 2 换行符
  3. 符号

4.2 元字符转义

在正则表达式中,某些字符有特殊的含义,如果要匹配这些特殊字符本身,需要使用反斜杠进行转义。例如

\+ 表示匹配一个加号字符

\* 表示匹配一个星号字符

4.3 Unicode转义

使用 \u 后面跟着四个十六进制数字,可以表示一个Unicode字符。例如 \u0041 表示匹配一个大写字母A。


4.4 双斜杠

需要注意的是,因为在字符串中,反斜杠也是一个转义字符。所以在/ /正则规则符外,字符串中需要使用双反斜杠 \\ 来表示,例如 \\. 表示匹配一个点字符。

let pattern = new RegExp("\\d")
//表示\b

5 限定符

在JavaScript中,正则表达式的限定符用于指定匹配元素的数量。以下是一些常见的正则表达式限定符:

5.1 普通限定符

*:匹配前面的元素零次或多次。 例如,/a*b/将匹配'a', 'ab', 'aab'等。

+:匹配前面的元素一次或多次。 例如,/a+b/将匹配'ab', 'aab', 'aaab'等。

?:匹配前面的元素零次或一次。 例如,/a?b/将匹配'b'和'ab'。还可以匹配禁止贪婪,匹配最小符合值


5.2 区间限定符

{n}:匹配前面的元素恰好n次。 例如,/a{2}b/将匹配'aab',但不匹配'ab'或'aaab'。

{n,}:匹配前面的元素至少n次。 例如,/a{2,}b/将匹配'aab','aaab'等。

{n,m}:匹配前面的元素至少n次,最多m次。 例如,/a{2,4}b/将匹配'aab','aaab'和'aaaab',但不匹配'ab'或'aaaaab'。


6 定位符

正则表达式中的定位符用于限定匹配的位置。以下是常见的正则表达式定位符:

6.1 开头和结尾

^:匹配字符串的开始位置。 例如:/^abc/ 匹配以 "abc" 开头的字符串。

$:匹配字符串的结束位置。 例如:/abc$/ 匹配以 "abc" 结尾的字符串。


6.2 边界单词

\b:匹配单词的边界。 例如:/\babc\b/ 匹配独立的 "abc" 单词,不匹配 "abcd" 或 "abcde"。

\B:匹配非单词的边界。 例如:/\Babc\B/ 匹配不包含 "abc" 的字符串。


6.3 肯定预查

(?=pattern):正向肯定预查。 例如:/abc(?=def)/ 匹配 "abc",且后面紧跟着 "def",但不包含 "def"。

(?<=pattern):反向肯定预查。 例如:/(?<=abc)def/ 匹配 "def",且前面紧跟着 "abc",但不包含 "abc"。


6.3 否定预查

(?<!pattern):反向否定预查。 例如:/(?<!abc)def/ 匹配 "def",但前面不能紧跟着 "abc"。

(?!pattern):正向否定预查。 例如:/abc(?!def)/ 匹配 "abc",但后面不能紧跟着 "def"。


7 修饰符

7.1 g 全局搜索

在整个字符串中查找所有匹配的模式。 示例:

  const regex = /hello/g;
  const str = 'hello world hello';
  const matches = str.match(regex);
  console.log(matches); // Output: ['hello', 'hello']

7.2 i 忽略大小写

在匹配时忽略模式和字符串的大小写。 示例:

const regex = /hello/i;
const str = 'Hello world';
const matches = str.match(regex);
console.log(matches); // Output: ['Hello']

7.3. m 多行搜索

允许模式匹配多行文本。 示例:

const regex = /^hello/m;
const str = 'hello world
			hello there';
const matches = str.match(regex);
console.log(matches); // Output: ['hello', 'hello']

7.4. u Unicode 匹配

启用 Unicode 匹配模式。 配合\p实用,script表示unicode中的语言类型 示例:

const regex = /^\p{Script=Han}+$/u;
const str = '你好';
const matches = str.match(regex);
console.log(matches); // Output: ['你好']

7.5. s dotAll 忽略换行

`. `匹配所有字符,但是不包括换行符。配合s修饰符就可以忽略换行符的影响来匹配所有

示例:

const regex = /hello.world/s;
//这个点是匹配规则,不是普通的点
const str = 'hello
					world';
const matches = str.match(regex);
console.log(matches); // Output: ['hello\nworld']

7.6 y 粘性匹配

通过从上次匹配的位置开始搜索来匹配目标字符串。表示连续的 示例:

const regex = /hello/y;
const str = 'hello hello world';
const matches = regex.exec(str);
console.log(matches); // Output: ['hello']
regex.lastIndex = 6;
const nextMatches = regex.exec(str);
console.log(nextMatches); // Output: ['hello']

这些修饰符可以单独使用,也可以组合使用。在 JavaScript 中,可以使用 RegExp 构造函数或字面量语法来创建正则表达式,并使用修饰符来调整正则表达式的行为。


7.7 额外-lastIndex

RegExp 对象lastIndex 属性可以返回或者设置正则表达式开始匹配的位置

必须结合 g 修饰符使用,对 exec 方法有效 匹配完成时,lastIndex 会被重置为 0,适合配合while()使用

let str = `我先凑个字数,我设定的索引是5,所以第一个‘我先凑’是匹配不到的,我26假装是字符串,我..不是真的字符串`;
//逗号表示任意字符
let reg = /我(.{2})/g;
reg.lastIndex = 5; //从索引10开始搜索
console.log(reg.exec(str));
console.log(reg.lastIndex);

reg = /\p{sc=Han}/gu;
while ((res = reg.exec(str))) {
  console.log(res[0]);
}



7.8 额外-g和y的区别

我们来对比使用 y 与g 模式,使用 g 模式会一直匹配字符串


let str= "asdfgasdfg";
let reg = /a/g;
console.log(reg.exec(str));//['a', index: 0, input: 'asdfgasdfg', groups: undefined]
console.log(reg.lastIndex); //1
console.log(reg.exec(str)); //['a', index: 5, input: 'asdfgasdfg', groups: undefined]
console.log(reg.lastIndex);//6
console.log(reg.exec(str)); //null
console.log(reg.lastIndex); //0




但使用y 模式后如果从 lastIndex 开始匹配不成功就不继续匹配了

let str= "asdfgasdfg";
let reg = /a/y;
console.log(reg.exec(str));//['a', index: 0, input: 'asdfgasdfg', groups: undefined]
console.log(reg.lastIndex); //1
console.log(reg.exec(str)); //null
console.log(reg.lastIndex);//0
console.log(reg.exec(str)); //['a', index: 0, input: 'asdfgasdfg', groups: undefined]
console.log(reg.lastIndex); //1


因为使用 y 模式可以在匹配不到时停止匹配,在匹配下面字符中的 连续的值 时可以提高匹配效率

let str = `我的手机号码是123456789,987654321,147258369`;

//?:匹配前面的元素零次或一次。
let reg = /(\d+),?/y;
reg.lastIndex = 7;
while ((res = reg.exec(str))) 

console.log(res[1]);
//123456789
// 987654321
// 147258369


8 调用原子组的多种方法

8.1 在字面量中的使用\1

let tel = "2022-02-23";
console.log(tel.match(/\d{4}([-\/])\d{2}\1\d{2}/));

在例题中d{2}\1中的\1就是表示第一个原子组,即前面的([-/])


8.2 在replace函数中的参数使用$1

replace方法不仅可以执行基本字符替换,也可以进行正则替换,下面替换日期连接符

let str = "2023/02/12";
console.log(str.replace(/\//g, "-")); //2023-02-12

替换字符串可以插入下面的特殊变量名:

变量说明
$$插入一个 "$"。
$&插入匹配的子串。
$`插入当前匹配的子串左边的内容。
$'插入当前匹配的子串右边的内容。
$n假如第一个参数是 RegExp 对象,并且 n 是个小于 100 的非负整数,那么插入第 n 个括号匹配的字符串。提示:索引是从 1 开始

在后盾人前后添加三个=

let hd = "1a2";
console.log(hd.replace(/a/g, "$`$`$&$'$'"));
//&表示匹配到的值
//$` 插入当前匹配的子串左边的内容。
//$' 插入当前匹配的子串右边的内容。
//   111a222

把电话号用 - 连接

let str= "(010)99999999 (020)8888888";
console.log(str.replace(/\((\d{3,4})\)(\d{7,8})/g, "$1-$2"));

把所有教育汉字加上链接 www.baidu.com

<body>
  百度是个浏览器,但是百度广告比较多
</body>
<script>
   const body = document.body;
    body.innerHTML = body.innerHTML.replace(/百度/g,
     `<a href="https://www.baidu.com">$&</a>` 
      );
</script>

为链接添加上https ,并补全 www.

<body>
    <main>
      <a style="color:red" href="http://www.baidu.com">
        百度
      </a>
      <a href="http://360.com">360</a>
      <a href="http://qq.com">qq</a>
      
    </main>
  </body>
  <script>
    const main = document.querySelector("body main");
    const reg = /(<a.*href=['"])(http)(:\/\/)(www\.)?(baidu|360)/gi;
    main.innerHTML = main.innerHTML.replace(reg, (v, ...args) => {
      args[1] += "s";
      args[3] = args[3] || "www.";
      return args.splice(0, 5).join("");
    });
  </script>

将标题标签全部替换为 p 标签

<body>
    <h1>360.com</h1>
    <h2>qq.com</h2>
    <h1>123</h1>
  </body>
  
  <script>
    const reg = /<(h[1-6])>(.*?)<\/\1>/g;
    const body = document.body.innerHTML;
    const html = body.replace(reg, function(str, tag, content) {
      return `<p>${content}</p>`;
    });
    document.body.innerHTML = html;
  </script>

删除页面中的 h1~h6 标签

<body>
  <h1>123</h1>
  <h2>456</h2>
  <h1>abc</h1>
  <p>上面的H标签被删除了</p>
</body>

<script>
    const reg = /<(h[1-6])>(.*?)<\/\1>/g;
    const body = document.body.innerHTML;
    const html = body.replace(reg, "");
    document.body.innerHTML = html;
</script>

8.2 在replace函数中的回调函数使用p1

replace 支持回调函数操作,用于处理复杂的替换逻辑

变量名代表的值
match匹配的子串。(对应于上述的$&。)
p1,p2, ...假如 replace()方法的第一个参数是一个 RegExp 对象,则代表第 n 个括号匹配的字符串。(对应于上述的11,2 等。)例如,如果是用 /(\a+)(\b+)/ 这个来匹配,p1 就是匹配的 \a+,p2 就是匹配的 \b+。
offset匹配到的子字符串在原字符串中的偏移量。(比如,如果原字符串是 'abcd',匹配到的子字符串是 'bc',那么这个参数将会是 1)
string被匹配的原字符串。
NamedCaptureGroup命名捕获组匹配的对象

使用回调函数将 后盾人 添加上链接

<body>
  <div class="content">
    百度是个浏览器,但是百度广告比较多
  </div>
</body>

<script>
  let content = document.querySelector(".content");
  content.innerHTML = content.innerHTML.replace("百度",function(search,pos,source){
    return `<a href="https://www.baidu.com">${search}</a>`;
  });
</script>

为所有标题添加上 hot 类

<body>
    <div class="content">
      <h1>123</h1>
      <h2>456</h2>
      <h1>789</h1>
    </div>
    <div>
        <h1>123</h1>
        <h2>456</h2>
        <h3>789</h3>
    </div>
  </body>
  <script>
    let content = document.querySelector(".content");
    let reg = /<(h[1-6])>([\s\S]*?)<\/\1>/gi;
    content.innerHTML = content.innerHTML.replace( reg, ( search,p1,p2,index,source ) => {
           //search, 匹配到的字符
        //p1, 第一个原子组
        //p2, 第二个原子组
        //p...类推
        //index, 索引位置
        //source 原字符
        return ` <${p1} class="hot">${p2}</${p1}> `;
      }
    );
  </script>
  <style>
    .hot {
      color: rgb(247, 94, 23);
      font-size: 20px;
  }
  </style>

9 正则中常用的方法

9.1 辅助性的方法

prompt()是JavaScript中的一个函数,用于在网页上弹出一个对话框,以便用户输入信息。

它的语法是:

let str = prompt(text, default)

其中,text是一个字符串,用于在对话框中显示提示信息,告诉用户要输入什么内容。

default是一个可选参数,用于设置对话框中文本输入框的默认值。

prompt()函数会返回用户在对话框中输入的字符串值。如果用户点击了取消按钮,或者没有输入任何内容而直接点击确定按钮,那么它的返回值将是null。

以下是一个使用prompt()函数的示例:

var name = prompt("请输入您的名字", "张三");
if (name != null) {
    alert("您好," + name + "!");
} else {
    alert("您取消了输入!");
}

在这个示例中,调用prompt()函数会弹出一个对话框,提示用户输入名字。如果用户输入了名字并点击确定按钮,那么弹出一个欢迎的提示框,否则弹出一个取消的提示框。


9.2 字符串中的方法search

search 方法用于在字符串中查找指定的子字符串或正则表达式,并返回第一个匹配项的索引。

下面是使用 search 方法的示例:

const str = 'Hello, world!';
const substring = 'world';

const index = str.search(substring);
console.log(index); // 输出:7

在上面的示例中,我们调用了 search 方法来查找子字符串 'world' 在字符串 'Hello, world!' 中的索引。由于子字符串 'world' 存在于字符串 'Hello, world!' 中,并且是第一个匹配项,因此返回了索引 7。

下面是 search 方法和正则表达式配合使用的示例:

const str = 'Hello, world!';
const pattern = /world/;

const index = str.search(pattern);
console.log(index); // 输出:7

在上面的示例中,我们使用正则表达式 /world/ 来查找字符串 'Hello, world!' 中的 'world' 子字符串。在这种情况下,search 方法将自动将字符串转换为正则表达式,并返回第一个匹配项的索引,因此仍然返回 7。


9.3 字符串中的方法match

在JavaScript中,match()方法是用来在字符串中查找与正则表达式匹配的子串,并返回匹配结果的方法。

match()方法的语法如下:

string.match(regexp)

其中,string是要进行匹配的字符串,regexp是一个正则表达式。

match()方法返回一个数组,其中包含所有匹配的子串。如果没有找到匹配的子串,返回值为null。

下面是一个match()方法的示例:

const str = "Hello, World!";
const pattern = /Hello/;
const result = str.match(pattern);
console.log(result);

输出结果为:["Hello"],因为字符串中存在与正则表达式匹配的子串"Hello"。

match()方法还支持使用全局标志(g)来搜索字符串中的所有匹配项,并将它们作为数组返回。

const str = "JavaScript is fun. JavaScript is cool.";
const pattern = /JavaScript/g;
const result = str.match(pattern);
console.log(result);

输出结果为:["JavaScript", "JavaScript"],因为字符串中有两个匹配的子串"JavaScript"。

match()方法也可以与正则表达式的其他修饰符一起使用,如忽略大小写(i):

const str = "Hello,Hello World!";
const pattern = /hello/i;
const result = str.match(pattern);
console.log(result);

输出结果为:["Hello"],因为使用了忽略大小写修饰符,正则表达式匹配到了子串"Hello"。

需要注意的是,如果正则表达式没有使用全局标志(g),则仅返回第一个匹配的子串的详细信息。

Array(1)
0: "Hello"
groups: undefined//原子组信息
index: 0//匹配到的第一个索引
input: "Hello,Hello World!"//被匹配的字符串
length: 1//匹配到的的个数
[[Prototype]]: Array(0)

使用全局标志时,返回所有匹配的子串。这时候会丢失详细的信息

(2) ['Hello', 'Hello']
0: "Hello"
1: "Hello"
length: 2
[[Prototype]]: Array(0)

9.4 字符串中的方法matchAll

在JavaScript中,matchAll()方法是字符串对象的一个方法。它返回一个包含所有匹配正则表达式的结果的迭代器。

matchAll()方法接受一个正则表达式作为参数,并且返回一个迭代器对象,该对象包含所有匹配结果的信息。

以下是matchAll()方法的使用示例:

const str = 'Hello, world!';
const regex = /\w+/g;
const matches = str.matchAll(regex);

for (const match of matches) {
  console.log(match);
}

输出结果将是:

["Hello", index: 0, input: "Hello, world!", groups: undefined]
["world", index: 7, input: "Hello, world!", groups: undefined]

在上面的示例中,我们首先创建了一个包含字符串的变量str,然后创建了一个正则表达式regex,该正则表达式用于匹配单词字符。接下来,我们使用matchAll()方法将正则表达式应用于字符串,并将结果保存在matches变量中。最后,我们使用for...of循环遍历matches迭代器,并输出每个匹配结果。


9.5 实现低版本中的matchAll

1.使用match递归实现 matchAll()方法是在ES2020中引入的。如果你使用的是较旧的JavaScript版本,可能不支持该方法。在这种情况下,你可以考虑使用其他方法来实现类似的功能

//在字符串原型上定义方法
String.prototype.matchAll = function(reg) {
//调用原型上的match方法,获得第一次匹配到的值
  let res = this.match(reg);
  //如果有匹配值,用符号来取代第一次匹配值的位置
  if (res) {
    let str = this.replace(res[0], "^".repeat(res[0].length));
    //再次递归调用,如果匹配不到时,则会返回null,这是用空数组来赋值
    let match = str.matchAll(reg) || [];
    //将每次第一次匹配上的值放入数组中,同时释放递归中下一层的match数组
    return [res, ...match];
  }
};
let str = "tyuiou";
console.dir(str.matchAll(/(U)/i));

2.使用exec配合g修饰符实现 这方法并不完美,因为它是利用exec()方法的lastindex属性实现的,说明它依赖于g修饰符,其实要是用上面那种符号替代的方式也是可以做到摆脱lastindex属性,进行完美实现的,不过这里就不进行讨论了

function matchAll(str, regex) {
  let matches = [];
  let match;
  while ((match = regex.exec(str)) !== null) {
    matches.push(match[0]);
  }
  return matches;
}
let str = "Hello world!";
let regex = /\w/g;
let matches = matchAll(str, regex);
console.log(matches);  


9.6 字符串中的方法split

JavaScript中的字符串方法split()用于将字符串拆分为一个字符串数组,根据指定的分隔符将字符串分成多个部分。

语法:

string.split(separator, limit)

参数:

  • separator:字符串或正则表达式,指定分隔符,用于确定如何拆分字符串。如果省略该参数,则返回包含整个字符串的数组。
  • limit:可选参数,指定返回的数组的最大长度。如果设置了该参数,则返回的数组将不会超过该长度。

返回值: 返回一个字符串数组。

示例:

var str = "apple,banana,orange";
var arr = str.split(",");
console.log(arr); // ["apple", "banana", "orange"]

var str2 = "hello world";
var arr2 = str2.split(" ");
console.log(arr2); // ["hello", "world"]

注意:

  • split()方法不会改变原始字符串。
  • 如果指定的分隔符在原始字符串中不存在,则返回一个包含整个字符串的数组。
  • 如果分隔符为空字符串或没有指定分隔符,则返回的数组中只包含一个元素,即原始字符串本身。
  • 如果分隔符位于字符串的开头或结尾,split()方法将在返回的数组中包含一个空字符串元素。

9.7 字符串中的replace

JavaScript中的字符串对象的replace()方法是用于查找并替换字符串中的特定字符或字符模式。它接受两个参数:第一个参数是要查找的字符或字符模式,第二个参数是用于替换的新字符串。

基本语法如下:

string.replace(searchValue, newValue)

第一个参数为字符串 例如,下面的代码将把字符串中的所有"world"替换为"JavaScript":

var str = "Hello world!";
var newStr = str.replace("world", "JavaScript");
console.log(newStr); // 输出 "Hello JavaScript!"

第一个参数为正则 replace()方法还可以接受一个正则表达式作为搜索模式,以便更灵活地进行搜索和替换。例如,以下代码将把字符串中的所有数字替换为空字符串:

var str = "1a2b3c4d";
var newStr = str.replace(/[0-9]/g, "");
console.log(newStr); // 输出 "abcd"

第二个参数为函数:

var str = "Hello world!";
var newStr = str.replace("world", match=> {
  return match.toUpperCase();
});
console.log(newStr); // 输出:Hello WORLD!

第二个参数为多参函数: 这种情况看目录8.2

注意 replace()方法默认只替换第一个匹配项。如果要替换所有匹配项,可以使用全局标志"g",例如:

var str = "Hello Hello Hello";
var newStr = str.replace(/Hello/g, "Hi");
console.log(newStr); // 输出 "Hi Hi Hi"

replace()方法不会修改原始字符串,而是返回一个新字符串作为结果。如果想修改原始字符串,需要将结果赋值给原始字符串:

var str = "Hello world!";
str = str.replace("world", "JavaScript");
console.log(str); // 输出 "Hello JavaScript!"

9.8 正则中的test

在JavaScript中,可以使用正则表达式对象的test()方法来测试一个字符串是否符合某个正则表达式的模式。

语法:

reg.test(str)

参数:

  • regexObj:一个正则表达式对象。
  • str:一个要被测试的字符串。

返回值:

  • 如果字符串符合正则表达式的模式,返回true
  • 如果字符串不符合正则表达式的模式,返回false

例子:

let regex = /\d+/;   // 匹配一个或多个数字
console.log(regex.test("123"));   // true
console.log(regex.test("abc"));   // false

注意:test()方法不会改变正则表达式对象的lastIndex属性,多次调用test()方法,返回结果不会受到这个属性的影响。


9.8 正则中的exec

exec() 是 JavaScript 中正则表达式对象的一个方法,用于在字符串中执行正则表达式的匹配操作。

区别execmatch
方法来源正则上的方法字符串上的方法
语法regexp.exec(str)str.exec(regexp)
非全局情况下返回单个详细信息返回单个详细信息
全局g情况下返回单个详细信息,每调用一次,返回下一个详细信息返回所有符合的一个数组,丢失详细信息
lastIndex只在在全局情况下,每次调用都会修改lastindex无法修改lastindex

参数:

  • regexp:一个正则表达式对象。
  • str:要匹配的字符串。

返回值:

  • 如果找到了匹配的字符串,则返回一个数组,数组中包含匹配的字符串以及其他的相关信息。
['Hello', index: 0, input: 'Hello,Hello World!', groups: undefined]
0: "Hello"
groups: undefined
index: 0
input: "Hello,Hello World!"
length: 1
[[Prototype]]: Array(0)

  • 如果没有找到匹配的字符串,则返回 null

exec() 方法在执行匹配操作时,会更新正则表达式对象的 lastIndex 属性,该属性用来指定下次匹配的起始位置。

下面是一个示例,展示了如何使用 exec() 方法:

let str = "This is a test string.";
let pattern = /test/;

let result = pattern.exec(str);

console.log(result); // 输出 ["test", index: 10, input: "This is a test string.", groups: undefined]
console.log(result[0]); // 输出 "test"
console.log(result.index); // 输出 10
console.log(result.input); // 输出 "This is a test string."

在这个例子中,我们创建了一个正则表达式对象 pattern,然后使用 exec() 方法在字符串 str 中执行匹配操作。因为字符串中包含了 "test" 这个子字符串,所以 exec() 返回了一个数组,数组中包含了匹配的字符串 "test" 以及其他的相关信息。我们可以通过数组的索引获取匹配的字符串,也可以通过属性访问其他的相关信息。