JavaScript——正则总结

Posted 、妤

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript——正则总结相关的知识,希望对你有一定的参考价值。

@

标记

g:全局匹配,默认返回匹配到第一个目标,加上该标记,返回所有匹配项。
i :忽略大小写,匹配中忽略大小写。

元字符

元字符:正则表达式中有着特殊含义的字符

单文本匹配的元字符(单个匹配)

任意一个文本匹配的元字符(单个匹配)

. :匹配任意一个单个字符(包括.本身);大多数语言环境中,不能匹配换行符

任意一个一组字符集匹配的字符(字符集合单个匹配)

【】:匹配【】中的任意一个成员文本。
注意:在字符集中使用像.和+这样的元字符将被解释为普通字符,不需要被转义,一般加上转义,明确目的。

常用如下字符集区间(可以是一个区间也可以是多个区间):
【0-9】:0到9字符;
【A-Z】:A到Z字符;
【a-z】:a到z字符;
【A-Za-z0-9】:任意字母和数字字符;
注意:字符区间的首,尾字符可以是ASCII字符表里的任意字符。注意首尾字符大小顺序,由小到大。

取非匹配

【^】:不匹配【】中的任意一个成员文本。

匹配特殊字符的元字符(单个匹配)

转义字符

\\:匹配正则表达式中的特殊字符(如:. 匹配普通.字符);
\\ 字符永远出现在特殊含义的字符序列(序列可以由一个或者多个字符构成)的开头。

匹配特定的空白字符的元字符

【\\b】:回退(并删除)一个字符(Backspace键)。
\\f:换页符。
\\n:换行符。
\\r:回车符。
\\t:制表符(TAB键)。
\\v:垂直制表符。

匹配特定字符集的元字符(字符类)

匹配任意一个数字和非数字

\\d:任何一个数字字符(等价于【0-9】)。
\\D:任何一个非数字字符(等价于【^0-9】)。

匹配任意一个字母和数字(与非字母和数字)

\\w:任何一个字母数字字符(大小写均可)或者下划线字符(等价于【a-zA-Z0-9_】)。
\\W:任何一个非字母数字或非下划线字符(等价于【^a-zA-Z0-9_】)。

匹配任意一个空白字符(与非空白字符)

\\s:任何一个空白字符(等价于【\\f\\n\\r\\t\\v】)。
\\S:任何一个非空白字符(等价于【^\\f\\n\\r\\t\\v】)。
注意:【\\b】是一个特列,没有包含在 \\s 和 \\S 中

匹配任意一个十六进制或八进制数值

\\x:匹配一个十六进制数值。如:\\x0A,对应于ASCII 字符10。
\\0:匹配一个八进制数值。如:\\011,对应于ASCII 字符9。

POSIX字符类

【:alnum:】:任何一个字母或数字(等价于【a-zA-Z0-9】)。
【:alpha:】:任何一个字母(等价于【a-zA-Z】)。
【:blank:】:任何一个空格或制表符(等价于【\\t】)。
【:cntrl:】:ASCII控制符(ASCII0到31,再加上ASCII127)。
【:digit:】:任何一个数字(等价于【0-9】)。
【:graph:】:和[:print:]一样,但不包括空格。
【:lower:】:任何一个小写字母(等价于【a-z】)。
【:print:】:任何一个可打印字符。
【:punct:】:既不属于【:alnum:】也不属于【:cntrl:】的任何一个字符。
【:space:】:任何一个空白字符,包括空格(等价于【^\\f\\n\\r\\t\\v】)。
【:upper:】:任何一个大写字母(等价于【A-Z】)。
【:xdigit:】:任何一个十六进制数字(等价于【a-fA-F0-9】)。

多个文本匹配的元字符(重复匹配)

匹配一个或多个字符

+:在一个字符(或字符集)加上+字符,匹配一个或者多个字符。至少匹配一个;

匹配零(0)个或多个字符

*:在一个字符(或字符集)加上*字符,匹配零个或者多个字符。至少匹配零个;

匹配零(0)个或一个字符

?:在一个字符(或字符集)加上?字符,匹配零个或者一个字符。最多不会超过一个字符;

匹配的重复次数(手动设定匹配次数)

{}:在一个字符(或字符集)加上{}字符,设置数值,设置匹配相应数值的字符。最多不会超过一个字符;

例子:
{3}: 设置重复次数;前面的匹配规则重复匹配三次
{3,6}:设置重复次数区间;前面的匹配规则重复匹配至少3次最多6次
{3,}:设置重复次数区间;前面的匹配规则重复匹配至少3次
{,6}:设置重复次数区间;前面的匹配规则重复匹配最多6次

防止过度匹配

在?元字符和{n}({n,m})手动设定匹配字符中,都有重复匹配次数的上限限制;
但是在其他重复匹配的语法中都没有上限限制;所以存在过度匹配(贪婪匹配)

?:添加在贪婪元字符的后面;防止过度匹配(将贪婪元字符变为惰性元字符)

常见的贪婪元字符为:* , + , n,
如:

* : *?
+ : +?
n, : n, ?

匹配位置的元字符

位置匹配解决,在什么地方进行字符匹配

单词边界

进行与单词有关的位置匹配

\\b : 匹配一个单词的开头或结尾(单词边界)
注意:\\b匹配且只匹配一个位置,不匹配任何字符;如:\\bcat\\b只匹配到字符串cat;3个字符,而不是5个字符。

\\B : 不匹配一个单词的单词边界

字符串边界

进行与字符串有关的位置匹配

^:匹配字符串开头的位置;
$:匹配字符串结尾的位置;

分行匹配模式

?m : 以行为单位进行匹配;
在分行模式中^不仅匹配正常字符串的开头,还匹配换行符(分隔符)后面开始的位置;
$不仅匹配正常字符串结尾,还将匹配换行符(分隔符)后面的结束位置。
注意:?m元字符用在整个匹配模式之前;如:(?m)^\\s//.$

子表达式

类似?和{n}等重复次数的元字符只作用于紧挨着它的前面的一个字符或元字符
而通过子表达式,将使?和{n}等重复次数的元字符作用于子表达式。
子表达式是更大的表达式一部分,子表达式将被当做一个独立元素来使用。

():创建子表达式;
子表达式用和 | 元字符相配合;返回多个不同子表达式结果

注意:子表达式可以无限嵌套,但应该遵循适可而止原子

回溯引用:前后一致匹配(子表达式另一重要用途)

子表示的用途:
将一个组字符编组为一个字符集合;设定该集合重复匹配的文本以及重复次数;
另一功能为,定义回溯引用,允许表达式引用前面的匹配结果。确保前后表达式匹配一致

回溯引用指的是模式的后半部分引用在前面部分中定义的子表达式
可以将回溯引用想象成变量

\\1 : 引用前面的第一个表达式;

数字需要对应相应的子表达式(不同语言环境,子表示开始计数通常为1,许多实现中,0可以代表整个正则表达式);
同一表达式可以被引用任意多次;

前后查找

通过表达式匹配文本的位置(而非文本本身),而通过该位置实现的向前或者向后查找。
注意:JavaScript不支持向后查找

向前查找

向前查找指定了一个必须匹配但不在结果中返回的模式

格式:
(实际匹配返回的文本)(?=匹配的文本模式,该文本不出现在返回的文本)

例子:
获取URL连接中的协议名
.+(?=:)

向前查找实际就是一个子表达式。
先前查找模式是以?=开头的子表达式,需要匹配的文本跟在=的后面

注意:向前查找(和向后查找)匹配本身其实是有返回结果的,只是这个结果的字符长度永远是0而已。
因为查找操作有时也被称为零宽度(zero-width)匹配操作

向后查找

格式:
(?<=匹配的文本模式,该文本不出现在返回的文本)(实际匹配返回的文本)

对前后查找取非

前后查找的目的是:指定返回的匹配文本的前后位置必须是哪些文本(匹配的文本模式);这种查找为正向前查找和正向后查找
术语"正":指的是寻找匹配的事实。
对应的有负前后查找;
负向前查找:向前查找不与给定模式匹配的文本;
负向后查找:向后查找不与给定模式匹配的文本;

负向前查找
操作符:?!

负向后查找
操作符: ?<!

嵌入条件

正则表达式里面的条件要用?来定义。

能嵌入条件时机不外乎发生以下两种情况:
根据一个回溯引用来进行条件处理。
根据一个前后查找来进行条件处理。

回溯引用条件

回溯引用条件只有在一个前面的子条件搜索取得成功的情况下才允许只用一个表达式。

格式:
(?(backer-ference)true-regex|false-regex)
(?(回溯引用)子表达式1 | 子表达式2 )
当回溯引用为真时,后面的子表达式1才会执行;当回溯引用为假时,后面的字表达2才会执行。

前后查找条件

前后查找条件只在一个向前查找或向后查找操作取得成功的情况下才允许一个表达式被使用。
定义前后查找的语法与定义一个回溯引用条件的语法大同小异,只需把回溯引用(括号里的回溯引用编号)替换为一个完整的前后查找表示式就行了

格式:
(?(?=匹配文本模式)true-regex|false-regex)
(?(?<=匹配文本模式)true-regex|false-regex)

实际工作中,嵌入了前后查找模式条件的模式相当少,特定位置的匹配往往可以通过?元字符实现。

JavaScript正则常用知识总结

一、JavaScript正则相关方法

str.match(regexp)与regexp.exec(str)功能类似。

str.search(regexp)与regexp.test(str)功能类似。

1. String.prototype.match()

检索匹配项,并返回匹配的第一个完整子串及其下捕获组捕获结果构成的数组(无g),或返回匹配的所有的完整子串(有g)

语法

str.match(regexp)
param:
  • regexp: 一个正则表达式对象。如果传入一个非正则表达式对象,则会隐式地使用 new RegExp(obj) 将其转换为一个 RegExp 。
return:
  • 如果正则表达式不包含g标志:会返回一个数组,数组的第一项是进行匹配完整的字符串,之后的项是用圆括号捕获的结果;数组还会包含一个 index属性,其值为匹配结果中的完整字符串在原字符串中的索引;数组还会包含一个 input属性, 其值为原字符串。此时返回的结果和 regexp.exec()返回的结果是完全相同的。

  • 如果正则表达式包含g标志:会返回一个数组,包含所有匹配的完整子字符串,但不包含匹配的捕获组捕获结果;也没有index属性和Input属性。

  • 如果提供了正则表达式,但是没有匹配到(无论是否带g): 返回null

  • 如果未提供任何参数,直接使用 match(): 返回一个包含空字符串的 Array :[""],同时该Array还包含index属性为0,input属性为原字符串 。

示例1: 正则表达式不带g, 带有捕获组, 且只有一个完整匹配

var str = ‘For more information, see Chapter 3.4.5.1‘;
var reg = /see (chapter d+(.d)*)/i;

var result = str.match(reg);

/* result:
[ 
  "see Chapter 3.4.5.1", 
  "Chapter 3.4.5.1", 
  ".1", 
  index: 22, 
  input: "For more information, see Chapter 3.4.5.1", groups: undefined
]
*/

// ‘see Chapter 3.4.5.1‘ 是整个匹配。
// ‘Chapter 3.4.5.1‘ 被‘(chapter d+(.d)*)‘捕获。
// ‘.1‘ 是被‘(.d)‘捕获的最后一个值。
// ‘index‘ 属性(22) 是整个匹配从零开始的索引。
// ‘input‘ 属性是被解析的原始字符串。

示例2:正则表达式带g, 带有捕获组, 且只有一个完整匹配

var str = ‘For more information, see Chapter 3.4.5.1‘;
var reg = /see (chapter d+(.d)*)/ig;

var result = str.match(reg);

/* result:

[
  "see Chapter 3.4.5.1"
]
*/

示例3:正则表达式带g, 不带捕获组,有多个完整匹配

var str = ‘ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz‘;
var regexp = /[A-E]/gi;
var result = str.match(regexp);

/* result:
["A", "B", "C", "D", "E", "a", "b", "c", "d", "e"]
*/

示例4:正则表达式带g, 带有捕获组,有多个完整匹配

var str = ‘ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz‘;
var regexp = /A(BCD)*/gi;
var result = str.match(regexp);

/* result:
["ABCD", "abcd"]
*/

示例5: 不传参数

var str = ‘ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz‘;

var result = str.match();

/* result:
[
  "", 
  index: 0, 
  input: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", 
  groups: undefined
  ]
*/

2. RegExp.prototype.exec()

在一个指定字符串中执行一个搜索匹配。返回一个结果数组或 null。并会更新正则表达式对象的属性。

语法

regExp.exec(str)
param
  • str:要匹配正则表达式的字符串
return
  • 如果匹配成功:会返回一个数组,数组的第一项是进行匹配完整的字符串,之后的项是用圆括号捕获的结果;数组还会包含一个 index属性,其值为匹配结果中的完整字符串在原字符串中的索引;数组还会包含一个 input属性, 其值为原字符串。

  • 如果匹配失败:exec() 方法返回 null。

返回的结果和 str.match(regexp) 中regexp不带有g时的返回的结果是完全相同的。

对正则表达式对象属性的更新

对原正则表达式对象做了以下属性的更新:

  • lastIndex: 下一次匹配开始的位置。就是匹配的完整字符串之后的下一个字符的索引。当正则对象含有 "g" 时,可以在同一个正则对象上多次执行 exec 方法来查找同一个字符串中的多个成功匹配。查找将从正则表达式的 lastIndex 属性指定的位置开始。
  • ignoreCase: 是否使用了 "i" 标记使正则匹配忽略大小写
  • global:是否使用了 "g" 标记来进行全局的匹配.
  • multiline:
    是否使用了 "m" 标记使正则工作在多行模式(也就是,^ 和 $ 可以匹配字符串中每一行的开始和结束(行是由 或 分割的),而不只是整个输入字符串的最开始和最末尾处。)
  • source:正则表达式的字符串(不含igm标记)

示例1

var regexp = /quicks(brown).+?(jumps)/ig;
var str = ‘The Quick Brown Fox Jumps Over The Lazy Dog, quick brown jumps‘;
var result1 = regexp.exec(str);

/* result1:
[
  "Quick Brown Fox Jumps", 
  "Brown", 
  "Jumps", 
  index: 4, 
  input: "The Quick Brown Fox Jumps Over The Lazy Dog, quick brown jumps", 
  groups: undefined
]
*/

// regexp:
regexp.lastIndex;//25 (即Jumps后面的那个空格符)
regexp.ignoreCase;//true
regexp.global;//true
regexp.multiline;//false
regexp.source;//"quicks(brown).+?(jumps)"


var result2 = regex.exec(str);

//result2:
/*
 [
  "quick brown jumps", 
  "brown", 
  "jumps", 
  index: 45, 
  input: "The Quick Brown Fox Jumps Over The Lazy Dog, quick brown jumps", 
  groups: undefined
]
*/

//regexp:
regexp.lastIndex;//62
regexp.ignoreCase;//true
regexp.global;//true
regexp.multiline;//false
regexp.source;//"quicks(brown).+?(jumps)"

3. String.prototype.search()

执行正则表达式和字符串之间的一个搜索匹配。返回字符串中首次完整匹配的索引或-1。

语法

str.match(regexp)
param
  • regexp: 一个正则表达式对象。如果传入一个非正则表达式对象,则会使用 new RegExp(obj) 隐式地将其转换为正则表达式对象。
return
  • 如果匹配成功:返回正则表达式在字符串中首次完整匹配的索引。
  • 如果匹配失败:返回 -1。

示例1:

var str = ‘ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz‘;
var regexp = /A(BCD)*/gi;
str.search(regexp); //0

4. RegExp.prototype.test()

执行一个检索,用来查看正则表达式与指定的字符串是否匹配。返回 true 或 false。

语法

regexp.test(str)
param
  • str: 用来与正则表达式匹配的字符串
return

Type Boolean.如果正则表达式与指定的字符串匹配 ,返回true;否则false。

5. String.prototype.replace

返回一个由替换值替换一些或所有匹配的模式后的新字符串。模式可以是一个字符串或者一个正则表达式, 替换值可以是一个字符串或者一个每次匹配都要调用的函数。原字符串不改变

语法

str.replace(regexp|substr, newSubStr|function)
params
  • pattern:
    • regexp: 一个RegExp对象或者RegExp字面量。该正则所匹配的内容会被第二个参数的返回值替换掉。
    • substr: 一个字符串。其会被第二个参数的返回值替换掉,由于该substr是被视为一个字符串而非正则,所以仅仅是第一个匹配会被替换。
  • replacement:
    • newSubStr: 用于替换掉第一个参数在原字符串中的匹配部分的字符串。该字符串中可以内插一些特殊的变量名。
    • function: 一个用来创建新子字符串的函数,该函数的返回值将替换掉第一个参数匹配到的结果。

newSubStr中可以插入的特殊变量名:

变量名 代表值
$$ ‘$‘
$& 匹配的子串
$` 当前匹配的子串左边的内容
$‘ 当前匹配的子串右边的内容
$n n为正整数,如果replace()方法的第一个参数是regexp,则表示第n个捕获组的匹配结果

function的参数:

变量名 代表值
match 匹配的子串。(对应于上述的$&。)
p1,p2, .. 如果replace()方法的第一个参数是一个RegExp,则代表第n个捕获组的匹配结果。(对应于上述的$1,$2等。)
offset 匹配到的子字符串在原字符串中的偏移量。(比如,如果原字符串是“abcd”,匹配到的子字符串是“bc”,那么这个参数将是1)
string 被匹配的原字符串。
return

匹配替换后的新字符串。原字符串不变。

示例1:使用function替换正则匹配结果

function replaceFunc(match, p1, p2, p3, offset, string) {
  return [p1, p2, p3].join(‘-‘);
}

var str = ‘abc12345#$*%‘;
var result = str.replace(/([^d]*)(d*)([^w]*)/, replaceFunc)//"abc-12345-#$*%"

示例2: 替换带有g标志的正则

var str = ‘Apples are round, and apples are juicy.‘; 
var result = str.replace(/apples/ig, ‘oranges‘);//‘oranges are round, and oranges are juicy‘.

示例3: 重组字符串中的多个子串

var str = ‘John Smith‘;
var result = str.replace(/(w+)s(w+)/,‘$2 and $1‘);//‘Smith and John‘

示例4: 将华氏温度转换为对应摄氏温度

function f2c(x)
{
  function convert(str, p1, offset, s)
  {
    return ((p1-32) * 5/9) + "C";
  }
  var s = String(x);
  var test = /(d+(?:.d*)?)F/g;
  return s.replace(test, convert);
}

示例5: 字符串去前后空格 经典!& 常用!

str.replace(/^s+|s+$/g, "");

二、常用匹配字符

1.字符类别

字符 含义
. 匹配任意单个字符,除了 u2028或u2029
d 匹配任意阿拉伯数字。等价于[0-9]
D 匹配任意不是阿拉伯数字的字符。等价于[^0-9]
w 匹配任意数字字母下划线。等价于[A-Za-z0-9_]
W 匹配任意不是数字字母下划线的字符。等价于[^A-Za-z0-9]
s 匹配一个空白符,包括空格、制表符、换页符、换行符、回车符合其他Unicode空格。等价于[ f vu00a0等等]
S 匹配一个非空白符
匹配一个水平制表符(tab)
匹配一个回车符(carriage return)
匹配一个换行符(linefeed)
v 匹配一个垂直制表符(vertical tab)
f 匹配一个换页符(form-feed)
[] 匹配一个退格符(backspace)(不要与  混淆)

2. 边界

字符 含义
^ 匹配输入开始。当有m标志时,将开始和结束字符(^和$)视为在多行上工作(也就是,分别匹配每一行的开始和结束(由 或 分割),而不只是只匹配整个输入字符串的最开始和最末尾处
$ 匹配输入结尾。 当有m标志时,将开始和结束字符(^和$)视为在多行上工作(也就是,分别匹配每一行的开始和结束(由 或 分割),而不只是只匹配整个输入字符串的最开始和最末尾处
 匹配一个零宽单词边界,如一个字母和一个空格之间。(不要和 [] 混淆)。例如,/no/ 匹配 "at noon" 中的 "no",/ly/ 匹配 "possibly yesterday." 中的 "ly"。
B 匹配一个零宽非单词边界,如两个字母之间或两个空格之间。例如, /Bon/匹配‘at noon‘中的‘on, /yeB/匹配‘possibly yesterday‘中的ye。

3. 断言

字符 含义
x(?=y) 仅匹配被y跟随的x。y可以是任意的正则字符组合。
x(?!y) 仅匹配不被y跟随的x。y可以是任意的正则字符组合。例如,举个例子,/d+(?!.)/ 只会匹配不被点(.)跟随的数字。

三. 验证常用正则表达式

1. 邮箱

简化版:

 /[email protected]S+.S+/

复杂版:

/^([A-Za-z0-9_-.])+@([A-Za-z0-9_-.])+.([A-Za-z]{2,4})$/

2. 用户名

用户名正则,4到16位(字母,数字,下划线,减号)

/^[a-zA-Z0-9_-]{4,16}$/

3. 满足一定强度的密码

最少6位,至少包括1个大写字母、1个小写字母、1个数字、1个特殊字符:

/^.*(?=.{6,})(?=.*d)(?=.*[A-Z])(?=.*[a-z])(?=.*[[email protected]#$%^&*? ]).*$/

检查某密码是否满足该强度:

var pattern=/^.*(?=.{6,})(?=.*d)(?=.*[A-Z])(?=.*[a-z])(?=.*[[email protected]#$%^&*? ]).*$/;
pattern.test(‘Ftc0615!#%^‘)//true

4. 手机号码正则

/^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(18[0,5-9]))d{8}$/

5. 身份证号正则

/^[1-9]d{5}(18|19|([23]d))d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)d{3}[0-9Xx]$/

四、分组与捕获括号

括号分为 捕获分组括号,和 仅用于分组的非捕获型括号两种。

1.捕获/分组括号:(...)

普通的无特殊意义的括号通常有两种功能:分组和捕获。

捕获型括号的编号是按照 开括号的次序,从左到右计算的。

如果提供了反向引用,则这些括号内的子表达式匹配的文本可以在表达式的后面部分使用$1、$2来引用。

2.仅用于分组的括号/非捕获型括号:(?:...)

仅用于分组的括号不能用来提取文本,而只能用来规定多选结构或者量词的作用对象。

它们不会按照$1、$2编号。

Example:

    (1|one)(?:and|or)(2|two)

这样匹配之后,$1包含‘1‘或‘one‘,$2包含‘2‘或‘two‘

参考资料

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/match
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp/exec
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/search
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/replace

https://www.jb51.net/article/115170.htm

《精通正则表达式》







以上是关于JavaScript——正则总结的主要内容,如果未能解决你的问题,请参考以下文章

javascript 正则表达式总结

JavaScript正则常用知识总结

密码强度的正则表达式(JavaScript)总结

JavaScript——正则总结

JavaScript 正则表达式学习

密码强度的正则表达式(JavaScript)总结