正则表达式

2023年 10月 12日 47.5k 0

第 1 章 字符组

字符组就是“一组”字符。在正则表达式中,它表示“在同一个位置可能出现的各种字符”。
写法:在一对方括号[]之间,列出所有可能出现的字符。例如:[abc]、[123]、[#?.]等

1.1 普通字符组

例如:检测字符串中是否存在数字

/[0123456789]/.test('hello123world');

字符组中字符的排列顺序并不影响字符组的功能,出现重复字符也不会影响。例如:[0123456789]完全等价于[9876543210][998876543210]

为了代码更容易编写、方便阅读,不推荐在字符组中出现重复字符,而且还应该让字符组中的字符排列更符合认知习惯。为此,正则表达式提供了**-范围表示法(range)**,它更直观,能进一步简化字符组。

所谓“-范围表示法”,就是用[x-y]的形式,表示 x 到 y 整个范围内的字符。[0123456789]就可以表示为[0-9]

1.1.1 范围表示法

“-范围表示法”的范围是如何确定的?为什么要写作[0-9],而不写作[9-0]?

在字符组中,-表示的范围,一般是根据字符对应的码值(字符在对应编码表中的编码数值)来确定的。码值小的字符在前,码值大的字符在后。在ASCII编码中,字符 0 的码值是48(十进制),字符9的码值是57(十进制)。所以[0-9]等价于[0123456789]

/[0-9]/.test('2')

image.png

在字符组中可以同时并列多个“-范围表示法”。例如:[0-9a-fA-F]可以匹配数字,大小写形式的a ~ f,它可以用来验证十六进制字符。

1.1.2 转义序列xnum表示字符

可以使用转义序列xnum来表示一个字符。其中x是固定前缀,表示转义序列的开头,num是字符对应的码值,是一个两位的十六进制数值。例如:字符A的码值是41(十进制则为65),所以也可以用x41表示。

字符组中有时会出现这种表示法,它可以表示一些难以输入或者难以显示的字符,比如x7f。也可以用来方便地表示某个范围,例如:

  • 所有标准ASCII字符对应的字符组:[x00-x7f],匹配码值范围[0,127]
  • 所有扩展ASCII字符对应的字符组:[x00-xff],匹配码值范围[0,255],可以用来匹配非中文字符。

1.2 元字符与转义

字符组中的横线-并不能匹配横线字符,而是用来表示范围,这类字符叫元字符。

字符组的开方括号[、闭方括号]、横线-、尖角号^都算元字符,在匹配中,有着特殊的意义。但有时候并不需要表示特殊的意义,只需要表示普通字符,此时就必须做特殊处理。

字符组中的-,如果它紧邻着字符组中的开方括号[或闭方括号],那么它就是普通字符,其他情况下都是元字符。

/[-9]/.test('-'); // true
/[9-]/.test('-'); // true

而对于其他元字符,取消特殊含义的做法都是转义,也就是在正则表达式中的元字符前加上反斜线字符

使用RegExp构造器创建正则,转义字符组中的横线-

new RegExp('[0\-2]');

仔细观察会发现,在正文里说“在正则表达式中的元字符之前加上反斜线字符”,而在代码里写的却不是[0-2],而是[0\-2]。因为在这段程序里,正则表达式是以字符串的方式提供的,而字符串本身也有关于转义的规定。上面说的“正则表达式”,是经过“字符串转义处理”之后的字符串的值。因为处理字符串时,反斜线和它之后的字符会被认为是转义序列。因此需要\ 转义成

1.3 排除型字符组

在方括号[...]中列出希望匹配的所有字符,这种字符组可以叫做“普通字符组”。它的确非常方便,但也有些问题是普通字符组不能解决的。比如匹配字符串中是否存在非数字字符,不是数字的字符太多了,全部列出几乎不可能,这时就应当使用排除型字符组。

排除型字符组非常类似普通字符串[...],只是在开方括号[之后紧跟一个尖角号^,写作[^...],表示“在当前位置,匹配一个没有列出的字符”。所以[^0-9]就表示“0 ~ 9之外的字符”,也就是“非数字字符”。

注意:排除型字符组必须匹配一个字符。

// 匹配一个除-、0、9之外的字符
/[^-09]/.test('-');  // false

// 匹配一个除0~9之外的字符
/[^0-9]/.test('a');  // true

在排除型字符组中,^是一个元字符,但只有它紧跟在[之后时才是元字符。如果想表示“这个字符组中可以出现^字符”,不要让它紧挨着[即可,否则就要转义。

/[0^9]/.test('^');   // true

1.4 字符组简记法

[0-9][a-z]等字符组,可以很方便地表示数字字符和小写字母字符。对于这类常用的字符组,正则表达式提供了更简单的记法,这就是字符组简记法。

常见的字符组简记法有dws

  • d等价于[0-9],其中的 d 代表“数字(digit)”。
  • w等价于[0-9a-zA-Z_],其中的 w 代表“单词字符(word)”。
  • s等价于[ nrtvf](第一个字符是空格),其中的 s 代表“空白字符(space)”。空白字符,可以是空格字符、新行换行符n、回车换行符r、水平制表符t、垂直制表符v、换页符f
/d/.test('2');   // true
/w/.test('a');   // true
/w/.test('_');   // true
/w/.test('2');   // true
/s/.test(' ');   // true

字符组简记法可以单独出现,也可以使用在字符组中。比如[0-9a-zA-Z]可以写成[da-zA-Z]
字符组简记法也可以用在排除型字符组中,比如[^0-9]可以写成[^d]

相对于dws这三个普通字符组简记法,正则表达式也提供了对应排除型字符组的简记法:DWS。字母完全一样,只是改为大写。

  • D等价于[^d][^0-9]
  • W等价于[^w][^0-9a-zA-Z_]
  • S等价于[^s][^ nrtvf]
// d 和 D
/d/.test('8');   // true
/d/.test('a');   // false
/D/.test('8');   // false
/D/.test('a');   // true

// w 和 W
/w/.test('c');   // true
/w/.test('!');   // false
/W/.test('c');   // false
/W/.test('!');   // true

// s 和 S
/s/.test('t');   // true
/s/.test('0');   // false
/S/.test('t');   // false
/S/.test('0');   // true

注意:[sS][wW][sS]能匹配任意字符。

关于字符组简记法,最后需要补充三点:

  • 如果字符组中出现了字符组简记法,最好不要出现单独的-,否则可能会引起错误,比如[d-a]就很让人困惑。
  • 以上说的dws的匹配规则,都是针对ASCII编码而言的,也叫ASCII匹配规则。而在一些语言中的正则表达式已经支持了Unicode字符。那么数字字符、单词字符、空白字符的范围,已经不仅限于ASCII编码中的字符。
  • 第 2 章 量词

    2.1 一般形式

    验证中国大陆地区的邮政编码(6位数字构成的字符串),比如201203

    只有同时满足以下两个条件,匹配才成功:

  • 长度是6个字符。
  • 每个字符都是数字。
  • /^dddddd$/.test('201203');   // true
    

    ^表示字符串的开头位置,$表示字符的结尾位置。

    d重复了6次,读写都不方便。为此,正则表达式提供了量词。比如上面匹配邮政编码的表达式,就可以简写为d{6},它使用阿拉伯数字,更简洁直观。

    /^d{6}$/.test('201203');   // true
    
    量词 说明
    {n} 之前的元素必须出现 n 次
    {n,m} 之前的元素最少出现 n 次,最多出现 m 次
    {n,} 之前的元素最少出现 n 次,最多无上限(隐式上限 65536)
    {0,n} 之前的元素可以不出现,也可以出现,最多出现 n 次

    注意:量词中的逗号之后不能有空格。
    术语:

    • 结构:一般指的是正则表达式所提供功能的记法。比如字符组就是一种结构。
    • 元素:指的是具体的正则表达式中的某个部分,比如某个具体表达式中的字符组[a-z],可以算作一个元素。元素,也叫“子表达式”。

    2.2 常用量词

    {n,m}是通用形式的量词,正则表达式还有3个常用量词,分别是+*?。它们的形态虽然不同于{n,m},功能却是相同的(也可以把它们理解为“量词简记法”)。

    常用量词 {n,m}等价形式 说明
    * {0,} 可能不出现,也可能出现,出现次数没有上限
    + {1,} 至少出现 1 次,出现次数没有上限
    ? {0,1} 至多出现 1 次,也可能不出现
    /^https?$/.test('http'); // true
    /^https?$/.test('https'); // true
    

    HTML标签匹配,分为开始标签、结束标签、自闭合单标签。例如:就是开始标签,就是结束标签,就是自闭合单标签。

  • 开始标签:/^
    • 结束。
    • 前不能是/、空白字符。
  • 结束标签:/^$/
    • 结束。
    • />结束

  • 相关文章

    服务器端口转发,带你了解服务器端口转发
    服务器开放端口,服务器开放端口的步骤
    产品推荐:7月受欢迎AI容器镜像来了,有Qwen系列大模型镜像
    如何使用 WinGet 下载 Microsoft Store 应用
    百度搜索:蓝易云 – 熟悉ubuntu apt-get命令详解
    百度搜索:蓝易云 – 域名解析成功但ping不通解决方案

    发布评论