JS中的正则表达式学习

JS中的正则表达式学习

参考:正则表达式完整教程

一. 正则表达式字符匹配

正则表达式是匹配模式,要么匹配字符,要么匹配位置。请记住这句话。

两种模糊匹配

横向模糊(不定长)和纵向模糊(不定字符)。

字符组

\d ,\D, \s, \S, [1-9], [^1-9] ,[adf]

量词

数量

  • {m,n} 至少m个,最多n个
  • ?
  • +
  • *
  • 量词末尾加?表示惰性匹配,默认是贪婪匹配

分支结构

就是或的意思,(hello|nihao)表示匹配hello或者nihao

二. 正则表达式位置匹配

什么是位置?

字符的首位位置

如何匹配位置?

  • ^ 开头,多行的行开头
  • $ 结尾,多行的行结尾
  • \b 单词的边界,也就是\w([0-9a-zA-Z_]) 和\W(以及^$)的之间的位置
  • \B 非单词边界
  • (?=p) 正向先行断言,匹配p前面的那个位置(换种说法,一个位置,它的后面是p)
  • (?!p) 负向先行断言,不匹配p前面的那个位置
  • (?<=p) 正向后行断言,匹配P后面的那个位置
  • (?<!=p) 负向后行断言,不匹配p后面的那个位置

位置的特性

对于位置的理解,我们可以理解成空字符""。
"hello" == "" + "h" + "" + "e" + "" + "l" + "" + "l" + "o" + "";

例子

  • 数字千分位替换:12345678 替换为 12,345,678
    (?<!^)(?=(\d{3})+(\.\d+)$) 替换为,

三. 正则表达式括号

分组((ab)+)和分支结构((p1|p2))

捕获分组

var regex = /(\d{4})-(\d{2})-(\d{2})/;
var string = "2017-06-12";
console.log( string.match(regex) ); 
// => ["2017-06-12", "2017", "06", "12", index: 0, input: "2017-06-12"]

替换

var regex = /(\d{4})-(\d{2})-(\d{2})/;
var string = "2017-06-12";
var result = string.replace(regex, "$2/$3/$1");
console.log(result); 
// => "06/12/2017"

等价于

var regex = /(\d{4})-(\d{2})-(\d{2})/;
var string = "2017-06-12";
var result = string.replace(regex, function(match, year, month, day) {
    return month + "/" + day + "/" + year;
});
console.log(result); 
// => "06/12/2017"

反向引用

比如要写一个正则支持匹配如下三种格式:
2016-06-12
2016/06/12
2016.06.12

var regex = /\d{4}(-|\/|\.)\d{2}(-|\/|\.)\d{2}/;
var string1 = "2017-06-12";
var string2 = "2017/06/12";
var string3 = "2017.06.12";
var string4 = "2016-06/12";
console.log( regex.test(string1) ); // true
console.log( regex.test(string2) ); // true
console.log( regex.test(string3) ); // true
console.log( regex.test(string4) ); // true

错误写法,会匹配 2016-06/12
假设我们想要求分割符前后一致怎么办?此时需要使用反向引用:

var regex = /\d{4}(-|\/|\.)\d{2}\1\d{2}/;
var string1 = "2017-06-12";
var string2 = "2017/06/12";
var string3 = "2017.06.12";
var string4 = "2016-06/12";
console.log( regex.test(string1) ); // true
console.log( regex.test(string2) ); // true
console.log( regex.test(string3) ); // true
console.log( regex.test(string4) ); // false

括号顺序以左括号为准

var regex = /^((\d)(\d(\d)))\1\2\3\4$/;
var string = "1231231233";
console.log( regex.test(string) ); // true
console.log( RegExp.$1 ); // 123
console.log( RegExp.$2 ); // 1
console.log( RegExp.$3 ); // 23
console.log( RegExp.$4 ); // 3

非捕获分组((?:p))

四. 正则表达式回溯法原理

假设我们的正则是/ab{1,3}c/

没有回溯的匹配

有回溯的匹配

常见的回溯形式

正则表达式匹配字符串的这种方式,有个学名,叫回溯法。
回溯法也称试探法,它的基本思想是:从问题的某一种状态(初始状态)出发,搜索从这种状态出发所能达到的所有“状态”,当一条路走到“尽头”的时候(不能再前进),再后退一步或若干步,从另一种可能“状态”出发,继续搜索,直到所有的“路径”(状态)都试探过。这种不断“前进”、不断“回溯”寻找解的方法,就称作“回溯法”。

简单总结就是,正因为有多种可能,所以要一个一个试。直到,要么到某一步时,整体匹配成功了;要么最后都试完后,发现整体匹配不成功。

  • 贪婪量词“试”的策略是:买衣服砍价。价钱太高了,便宜点,不行,再便宜点。
  • 惰性量词“试”的策略是:卖东西加价。给少了,再多给点行不,还有点少啊,再给点。
  • 分支结构“试”的策略是:货比三家。这家不行,换一家吧,还不行,再换。

五. 正则表达式的拆分

结构和操作符

js正则结构:字符字面量、字符组、量词、锚字符、分组、选择分支、反向引用。

  1. 转义符 \
  2. 括号和方括号 (...)、(?:...)、(?=...)、(?!...)、[...]
  3. 量词限定符 {m}、{m,n}、{m,}、?、*、+
  4. 位置和序列 ^ 、$、 \元字符、 一般字符
  5. 管道符(竖杠)|

上面操作符的优先级从上至下,由高到低。

posted @ 2022-12-17 22:32  杨万里fff  阅读(66)  评论(0)    收藏  举报