首页 > 其他分享 >【正则】954- 正则表达式有几种字符匹配模式?

【正则】954- 正则表达式有几种字符匹配模式?

时间:2022-09-30 12:02:18浏览次数:50  
标签:字符 匹配 正则表达式 954 leo 正则 let test match

【正则】954- 正则表达式有几种字符匹配模式?_正则

最近再一次重温老姚大佬的《JavaScript 正则表达式迷你书》 , 并将核心知识点整理一遍,方便复习。

原书写得非常棒,建议看下原书啦。  地址:https://github.com/qdlaoyao/js-regex-mini-book


原书这么一句话,特别棒:正则表达式是匹配模式,要么匹配字符,要么匹配位置,要记住。

1. 两种模糊匹配

正则表达式的强大在于它的模糊匹配,这里介绍两个方向上的“模糊”:横向模糊和纵向模糊。

  • 横向模糊匹配

即一个正则可匹配的字符串长度不固定,可以是多种情况。

如 ​​/ab{2,5}c/​​​ 表示匹配:第一个字符是 ​​"a"​​​ ,然后是 2 - 5 个字符 ​​"b"​​​ ,最后是字符 ​​"c"​​ :

let r = /ab{2,5}c/g;
let s = "abc abbc abbbc abbbbbbc";
s.match(r); // ["abbc", "abbbc"]
  • 纵向模糊匹配

即一个正则可匹配某个不确定的字符,可以有多种可能。

如 ​​/[abc]/​​​ 表示匹配 ​​"a", "b", "c"​​ 中任意一个。

let r = /a[123]b/g;
let s = "a0b a1b a4b";
s.match(r); // ["a1b"]

2. 字符组

  • 范围表示法

可以指定字符范围,比如 ​​[1234abcdUVWXYZ]​​​ 就可以表示成 ​​[1-4a-dU-Z]​​​ ,使用 ​​-​​ 来进行缩写。

如果要匹配 ​​"a", "-", "z"​​​ 中任意一个字符,可以这么写:​​[-az]​​​ 或 ​​[a\-z]​​​ 或 ​​[az-]​​ 。

  • 排除字符组

即需要排除某些字符时使用,通过在字符组第一个使用 ​​^​​​ 来表示取反,如 ​​[^abc]​​​ 就表示匹配除了 ​​"a", "b", "c"​​ 的任意一个字符。

  • 常见简写形式

字符组

具体含义

​\d​

表示 ​​[0-9]​​,表示一位数字。

​\D​

表示 ​​[^0-9]​​,表示除数字外的任意字符。

​\w​

表示 ​​[0-9a-zA-Z_]​​,表示数字、大小写字母和下划线。

​\W​

表示 ​​[^0-9a-zA-Z_]​​,表示非单词字符。

​\s​

表示 ​​[\t\v\n\r\f]​​,表示空白符,包含空格、水平制表符、垂直制表符、换行符、回车符、换页符。

​\S​

表示 ​​[^\t\v\n\r\f]​​,表示非空白字符。

​.​

表示 ​​[^\n\r\u2028\u2029]​​ 。通配符,表示几乎任意字符。换行符、回车符、行分隔符和段分隔符除外。

然后表示任意字符,就可以使用 ​​[\d\D]​​​、​​[\w\W]​​​、​​[\s\S]​​​ 和 ​​[^]​​ 任意一个。

3. 量词

量词也称重复,常用简写如下:

量词

具体含义

​{m,}​

表示至少出现 m 次。

​{m}​

等价于 ​​{m, m}​​ ,表示出现 m 次。

​?​

等价于 ​​{0, 1}​​ ,表示出现或不出现。

​+​

等价于 ​​{1, }​​ ,表示至少出现1次。

​*​

等价于 ​​{0, }​​ ,表示出现任意次,也有可能不出现。

  • 贪婪匹配和惰性匹配

在正则 ​​/\d{2,4}/​​ ,表示数字连续出现 2 - 4 次,可以匹配到 2 位、 3 位、4 位连续数字。

但是在 贪婪匹配 如 ​​/\d{2,4}/g​​ ,会尽可能多匹配,如超过 4 个,就只匹配 4 个,如有 3 个,就匹配 3 位。

而在 惰性匹配 如 ​​/\d{2,4}?/g​​ ,会 尽可能少 匹配,如超过 2 个,就只匹配 2 个,不会继续匹配下去。

let r1 = /\d{2,4}/g;
let r2 = /\d{2,4}?/g;
let s = "123 1234 12345";
s.match(r1); // ["123", "1234", "1234"]
s.match(r2); // ["12", "12", "34", "12", "34"]

惰性量词

贪婪量词

​{m,m}?​

​{m,m}​

​{m,}?​

​{m,}​

​??​

​?​

​+?​

​+​

​*?​

​*​

4. 多选分支

即提供多个子匹配模式任选一个,使用 ​​|​​(管道符)分隔,由于分支结构也是惰性,即匹配上一个后,就不会继续匹配后续的。

格式如:​​(r1|r2|r3)​​​,我们就可以使用 ​​/leo|pingan/​​​ 来匹配 ​​"leo"​​​ 和 ​​"pingan"​​。

let r = /leo|pingan/g;
let s = "leo cool,pingan good.";
s.match(r);// ["leo", "pingan"]

// 多选分支的惰性表现
let r1 = /leo|leooo/g;
let r2 = /leooo|leo/g;
let s = "leooo";
s.match(r1);// ["leo"]
s.match(r2);// ["leooo"]

5. 分组命名 (ES9)

ES9 之前的分组是通过数字命名的:

const pattern = /(\d{4})-(\d{2})-(\d{2})/u;
const result = pattern.exec('2020-01-05');
console.log(result[0]); // 打印"2020-01-05"
console.log(result[1]); // 打印"2020"
console.log(result[2]); // 打印"01"
console.log(result[3]); // 打印"05"

现在可以通过指定分组的名称,增加代码可读性,便于维护:

const pattern = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/u;
const result = pattern.exec('2020-01-05');
console.log(result.groups.year); // 打印"2020-01-05"
console.log(result.groups.month); // 打印"01"
console.log(result.groups.day); // 打印"05"

分组命名还可以和 ​​String.prototype.replace​​ 方法结合:

const reDate = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
const d = '2020-01-05';
const USADate = d.replace(reDate, '$<month>-$<day>-$<year>');
console.log(USADate); // 01-05-2020

6. 忽略分组

如果不希望捕获某些分组,在分组内加上 ​​?:​​​ 即可。比如 ​​(?:tom).(ok)​​​ 那么这里 ​​$1​​​ 指的就是 ​​ok​​。

7. 案例分析

匹配字符,无非就是字符组、量词和分支结构的组合使用。

  • 十六进制颜色值匹配
let r = /#[0-9a-fA-F]{6}|#[0-9a-fA-F]{3}/g;
let s = "#ffaacc #Ff00DD #fFF #01d #9Gd";
s.match(r); // ["#ffaacc", "#Ff00DD", "#fFF", "#01d"]
  • 时间和日期匹配
// 时间 12:23 或 01:09
let r = /^([01][0-9]|[2][0-3]):[0-5][0-9]$/;
r.test("23:25"); // true
r.test("03:05"); // true

// 时间 12:23 或 1:9
let r = /^(0?[0-9]|1[0-9]|[2][0-3]):(0?[0-9]|[1-5][0-9])$/;
r.test("23:25"); // true
r.test("03:05"); // true
r.test("3:5"); // true

// 日期 yyyy-mm-dd
let r = /^[0-9]{4}-(0[1-9]|[1][0-2])-(0[1-9]|[12][0-9]|3[01])$/;
r.test("2019-09-19"); // true
r.test("2019-09-32"); // false
  • Windows操作系统文件路径匹配

盘符使用 ​​[a-zA-Z]:\\​​​ ,这里需要注意 ​​\​​​ 字符需要转义,并且盘符不区分大小写;
文件名或文件夹名,不能包含特殊字符,使用 ​​​[^\\:*<>|"?\r\n/]​​​ 表示合法字符;
并且至少有一个字符,还有可以出现任意次,就可以使用 ​​​([^\\:*<>|"?\r\n/]+\\)*​​​ 匹配任意个 ​​文件夹\​​​;
还有路径最后一部分可以是 ​​​文件夹​​​ ,即没有 ​​\​​​ 于是表示成 ​​([^\\:*<>|"?\r\n/]+)?​​。

let r = /^[a-zA-Z]:\\([^\\:*<>|"?\r\n/]+\\)*([^\\:*<>|"?\r\n/]+)?$/;
r.test("C:\\document\\leo\\a.png"); // true
r.test("C:\\document\\leo\\"); // true
r.test("C:\\document"); // true
r.test("C:\\"); // true
  • id匹配

如提取 ​​<div id="leo" class="good"></id>​​​ 中的 ​​id="leo"​​ :

let r1 = /id=".*"/;    // tips1
let r2 = /id=".*?"/; // tips2
let r3 = /id="[^"]*"/; // tips3

let s = '<div id="leo" class="good"></id>';
s.match(r1)[0]; // id="leo" class="good"
s.match(r2)[0]; // id="leo"
s.match(r3)[0]; // id="leo"

tips1:由于 ​​.​​​ 匹配双引号,且 ​​*​​​ 贪婪,就会持续匹配到最后一个双引号结束。
tips2:使用惰性匹配,但效率低,有回溯问题。
tips3:最终优化。

【正则】954- 正则表达式有几种字符匹配模式?_正则_02


标签:字符,匹配,正则表达式,954,leo,正则,let,test,match
From: https://blog.51cto.com/u_11887782/5725734

相关文章

  • java 正则匹配输出匹配内容
    正则表达式规则查看我其他地方的详解:linux正则表达式正则表达式与系统无关,与语言无关,都是统一规则java使用常规用法一publicstaticvoidmain(String[]args){......
  • 正则表达式
    正则表达式符号描述?0个或1个,它就像是可选链操作符*0个或1个或多个+1个或多个......
  • 正则表达式中^的用法
    在使用正则表达式^的时候,有两层意思一限定开头放在规则的开头部分,表示限定开头/^a/表示以a开头 二(否)取反在中括号”[]”中被使用的话就是表示字符类的否定,在这个字......
  • 常见正则
    常见正则手机号/^1\d{10}$|^[2-9]\d{6,7}$|^[48]00\d{7}$|^[19]\d{4}$|^1\d{2}$/;邮箱/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-......
  • php 正则获取所有标签
    <?php$temp='<divclass="num">1</div><divclass="num">2</div><divclass="num">3</div><divclass="num">4</div><divclass="num1">3</div>&l......
  • JS 正则表达式
    普通字符普通字符包括没有显式指定为元字符的所有可打印和不可打印字符。这包括所有大写和小写字母、所有数字、所有标点符号和一些其他符号。字符描述[ABC]匹配 [...] 中......
  • JavaScript——正则表达式
    正则表达式                                                         ......
  • Oracle中的正则表达式(及函数)
    运算符在介绍函数前,这里先说明一下Oracle中正则表达式运算符及其描述。如果不知道他们有什么用,或者也不知道描述说的是什么,没关系,可以先看后面的介绍,就知道他们的含义了......
  • python-正则表达式re模块
    07、正则表达式学习正则表达式操作字符串re模块是用C语言写的没匹配速度非常快其中compile函数根据一个模式字符串和可选的标志参数生成一个正则表达式对象,该对象拥有......
  • .NET教程 - 字符串 & 编码 & 正则表达式(String & Encoding & Regular Express)
    更新记录转载请注明出处:2022年9月28日发布。2022年9月28日从笔记迁移到博客。System.char说明singleUnicodecharacteraliasestheSystem.Charstructcharc......