正则表达式必知必会

正则表达式

Regular Expression(regex)

正则表达式是用于匹配字符串中字符组合的模式。在 JavaScript中,正则表达式也是对象。这些模式被用于 RegExpexectest 方法, 以及 StringmatchmatchAllreplacesearchsplit 方法。(出自MDN)

是文本处理最强大的工具,主要用来完成搜索和替换工作

为什么使用正则表达式

通过使用正则表达式,可以:

  • 测试字符串内的模式。
    例如,可以测试输入字符串,以查看字符串内是否出现电话号码模式或信用卡号码模式。这称为数据验证。
  • 替换文本。
    可以使用正则表达式来识别文档中的特定文本,完全删除该文本或者用其他文本替换它。
  • 基于模式匹配从字符串中提取子字符串。
    可以查找文档内或输入域内特定的文本。

构造正则表达式的方法和创建数学表达式的方法一样。也就是用多种元字符运算符可以将小的表达式结合在一起来创建更大的表达式。正则表达式的组件可以是单个的字符字符集合字符范围字符间的选择或者所有这些组件的任意组合。

正则表达式是由普通字符(例如字符 a 到 z)以及特殊字符(称为"元字符")组成的文字模式(pattern)。模式描述在搜索文本时要匹配的一个或多个字符串。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。

修饰符

var str = "123abc";
var patt1 = /^[0-9]+abc$/; //正则表达式
document.write(str.match(patt1));

以^开头,$结尾

修饰符 含义 描述
i ignore - 不区分大小写 将匹配设置为不区分大小写,搜索时不区分大小写: A 和 a 没有区别。
g global - 全局匹配 查找所有的匹配项。
m multi line - 多行匹配 使边界字符 ^$ 匹配每一行的开头和结尾,记住是多行,而不是整个字符串的开头和结尾。
s 特殊字符圆点 . 中包含换行符 \n 默认情况下的圆点 . 是 匹配除换行符 \n 之外的任何字符,加上 s 修饰符之后, . 中包含换行符 \n。
/^123$/i   //忽略大小写
/^123$/g   //全局匹配
/^123$/m   //多行匹配

语法

1.匹配单个字符

匹配纯文本: /Ben/

匹配多个:/Ben/g

不区分大小写:/Ben/gi

匹配任意字符:/c.t/ 匹配cot cat 注意:.可以匹配任意的字符,字母,数字甚至是.本身

转义字符:/.a.\./ 匹配na1.xls sa1.xls scale.xls 注意:匹配特殊字符,例如.,加\转义

2.匹配一组字符

字符集合区间: /[ns]a.\\.xls/ 匹配na1.xls sa1.xls 不匹配ta1.xls

连字符-: /[ns]a[0-9]\.xls/ 匹配na1.xls sa2.xls 不匹配nat.xls 注意:-匹配规则符合ASCII码顺序

取非匹配: /[^0-9]/ 匹配非数字

3.元字符

转义字符:/myArray\[0\]/ 匹配 myArray[0]

3-1.空白元字符

\f 匹配一个换页符。等价于 \x0c 和 \cL。
\n 匹配一个换行符。等价于 \x0a 和 \cJ。
\r 匹配一个回车符。等价于 \x0d 和 \cM。
\s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。
\S 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。
\t 匹配一个制表符。等价于 \x09 和 \cI。
\v 匹配一个垂直制表符。等价于 \x0b 和 \cK。

windows匹配空白行/\r\n\r\n/

linux/unix匹配空白行 /\n\n/

3-2.数字元字符

\d 匹配一个数字字符。等价于 [0-9]。
\D 匹配一个非数字字符。等价于 [^0-9]

3-3 数字字母元字符

\w 匹配字母、数字、下划线。等价于[A-Za-z0-9_]。
\W 匹配非字母、数字、下划线。等价于 [^A-Za-z0-9_]

4. 重复匹配

匹配一个或多个字符(集合):/[0-9]+/  匹配数字
匹配0个或多个字符(集合):/1*/
匹配0个或者1个字符(集合):

/https?://[\w\.]*// 匹配网址
/\r?\n\r?\n/ 匹配空白行(兼容windows,linux,unix)
匹配n次:
/#[0-9a-fA-F]{6}/ 匹配RGB值
重复匹配设定区间:
/[\d]{4}[.-][\d]{1,2}[.-][\d]{1,2}/ 匹配年月日
匹配至少重复多少次:
/[2]{2,}/ 匹配2至少出现两次

防止发生过度匹配

例如

<a>123</a> ttt <a>456</a>

上面的如果用
/<a>.*</a>/g 匹配会是什么结果
贪婪型 懒惰型
* *?
+ +?
{n,}?

5.位置匹配

单词边界:
/\bcat\b/ 匹配 the cat scattered his food all over the room. 
字符串边界
/^<\?xml.*>/ 匹配 xml文件
分行匹配
(?m)^\s*/{2}.*$ 匹配注释

6. 子表达式

匹配IP地址
(\d{1,3}\.){3}\d{1,3}
子表达式嵌套:
ip地址改进:
//合法的ip地址必须满足
1. 任意一个1位数字或2位数组
2. 任意一个以1开头的三位数字
3. 任意一个以2开头,第二位不超过4的三位数字
4. 任意一个以2开头,第二位为5,第三位不超过5的三位数字
上面的\d{1,3}替换为
\d{1,2}|1\d{2}|2[0-4]\d|25[0-5]

7.回溯引用

子表达式可以在pattern的内部被引用,称为回溯引用

引用标题标签:
<[hH]([1-6])>.*?</[hH]\1>
用回溯引用实现文本替换:
1. 将电子邮箱替换为a链接
([\w]+[\w.]*@[\w.]*\.[\w]+)
<a href="mailto:$1">$1</a>

大小写转换

元字符 说明
\E 结束\L或\U转换
\L 从\L至\E转换为小写
\U 从\U至\E转换为大写
\l 下一个字符转换为小写
\u 下一个字符转换为大写

所有h1内容转为大写

(<[Hh]1>(\.*?)</[Hh]1>)
$1\U$2\E$3

8.前后查找

例如,当查找<title>标签中的内容,但是并不希望查找title标签本身

<head>
	<title>123</title>
</head>

常见的正则表达式实现支持向前查找,但是不是所有的语言都支持向后查找

Java,.net,PHP支持向后查找,但是有限制

JavaScript不支持向后查找

(向前查找)查找url中的协议
.+?(?=:) 查找 http://www.baidu.com ftp://ftp.123.123 https://www.qq.com
?=表示只要找到:就可以了,但是在最后的结果中不包含它
(向后查找)查找金额
(?<=\$)[0-9.]+  

上面称为正向前查找 正向后查找

对向前查找 和 向后查找 取非 称为 负向前查找负向后查找 其实就是取非操作

表示 负向前查找?! 负向后查找?<!

9.嵌入条件

匹配(123)456-789 或者123-456-789

最容易想到的方案

\(?\d{3}\)?-?\d{3}-\d{3}

但是这种同样会匹配到

(123456-789

(123)-456-789

出现问题的原因:有左括号的时候匹配右括号,此时不匹配-

这种情况下必须使用条件匹配

嵌入条件使用?,包括根据回溯引用前后查找使用条件查找

9-1 回溯引用条件

只在前面一个子表达式搜索成功的情况下才允许使用一个表达式.

(\()?\d{3}(?(1)\)|-)\d{3}-\d{3}

9-2 前后查找条件

只在一个向前查找或向后查找成功时允许使用一个表达式

和回溯引用条件类似,只需要把括号内的回溯引用编号换成前后查找表达式就可以了

例:匹配ZIP编码 格式如12345或12345-1234
\d{5}(?(?=-)-\d{4}

JavaScript中的正则表达式

对象

let pattern = new RegExp("123")
let pattern2 = /123/g

方法

exec 一个在字符串中执行查找匹配的RegExp方法,它返回一个数组(未匹配到则返回 null)。
test 一个在字符串中测试是否匹配的RegExp方法,它返回 true 或 false。
match 一个在字符串中执行查找匹配的String方法,它返回一个数组,在未匹配到时会返回 null。
matchAll 一个在字符串中执行查找所有匹配的String方法,它返回一个迭代器(iterator)。
search 一个在字符串中测试匹配的String方法,它返回匹配到的位置索引,或者在失败时返回-1。
replace 一个在字符串中执行查找匹配的String方法,并且使用替换字符串替换掉匹配到的子字符串。
split 一个使用正则表达式或者一个固定字符串分隔一个字符串,并将分隔后的子字符串存储到数组中的 String 方法。
posted @ 2021-10-13 20:26  cheeliu  阅读(444)  评论(0)    收藏  举报