JS宏进阶:正则表达式介绍
正则表达式(Regular Expression)是一种用于匹配字符串中字符组合的模式。它使用特定的语法和字符,可以高效地查找、替换或验证字符串中符合规则的内容。正则表达式在许多编程语言中都有广泛的应用,JavaScript也不例外。
一、正则表达式概述
1、普通字符与元字符
普通字符:大多数字符仅能够描述它们本身,如字母、数字等。例如 a 匹配 a,1 匹配 1 等。
元字符:具有特殊含义的字符,可以极大提高正则表达式的灵活性和匹配功能。总结如下
符号 | 解释 |
---|---|
. | 英文状态下的小数点,代表除换行符之外的任何单个字符。 |
* | 英文状态下的星号,表示匹配前面的字符或子表达式零次或多次。 |
+ | 英文状态下的加号,表示匹配前面的字符或子表达式一次或多次。 |
? | 英文状态下的问号,表示匹配前面的字符或子表达式零次或一次。 |
{n} | n代表数字,用花括号括起来表示前面的字符或子表达式恰好出现 n 次。 |
{n, m} | n, m都是数字,用花括号括起来表示前面的字符或子表达式恰好出现 n 次但不超过m次。 |
^ | 按键shift+6输入,表示输入字符串的开始位置。如:^a,表示开头是a |
$ | 按键shift+4输入,表示字符串的结束位置。如:a$,已a结尾 |
[abcd] | 字符类,表示匹配方括号中的任意一个字符。 |
[^abcd] | 否定字符类,匹配不在方括号中的任意一个字符。 |
| | 或操作符,匹配左侧或右侧的任意一个模式。 |
\ | 转义字符,用于将元字符或特殊字符转义为普通字符,或引入特殊序列。比如:\[ |
\d | 匹配一个数字,等价于:[0-9] |
\D | 匹配一个非数字字符,等价于:[^0-9] |
\w | 匹配一个字母、数字或英文下划线,等价于:[A-Za-z0-9_] |
\W | 匹配一个非字母、数字或英文下划线的字符,等价于:[^A-Za-z0-9_] |
\s | 匹配任何一个空白符,等价于:[ \f\n\r\t\v] |
\S | 匹配一个不属于空白符的任何字符,等价于:[^\s] |
\b | 匹配一个单词边界,即字与空格之间的位置。 |
\B | 非单词边界。 |
\t | 制表符,一个tap键(大写锁定上方按键),相当于四个空格 |
\n | 换行符,相当于一个enter键 |
\f | 匹配一个换页符 |
\v | 匹配一个垂直制表符 |
( ) | 分组,用于提取匹配的部分或应用量词。 |
(?:pat) | 非捕获组,用于分组但不捕获匹配的结果。 |
(?=pat) | 正向肯定预查,匹配某个模式,但不消耗字符。 |
(?!pat) | 负向肯定预查,匹配某个模式不存在的位置。 |
(?<=pat) | 正向否定预查,匹配某个模式前面的位置。 |
(?<!pat) | 负向否定预查,匹配某个模式不存在的位置。 |
顺便一提:\Z 也是一个元字符,它匹配字符串的结束位置。如果字符串以换行符结尾,\Z 会在换行符之前的位置匹配,而不是在字符串的末尾匹配。这个“增强”是由 Perl 引入的,并被许多正则表达式引擎所复制,包括 Java、.NET 和 PCRE(Perl Compatible Regular Expressions),但并不是所有引擎都支持,在WPS编辑器中,部分关于\Z的写法无法生效。
2、字符类与字符范围
字符类:是使用元字符 [ ] 来定义的,可以匹配方括号中的任意一个字符。例如:[abc]表示匹配一个a、b或c
字符范围:在方括号中使用连字符 - 表示一个范围。例如,[a-z]:表示任意一个小写字母。
3、量词
量词用于指定某个模式出现的次数(也就是 "."、"*"、"?"等元字符构成的),可以单独使用,也可以与字符类、字符组等结合使用。例如:
\d+:匹配一个以上的数字
\w+:匹配一个或以上的字母、数字或下划线
\d{1, 11}:匹配一个以上,但不超过11个的数字字符
4、边界符
指元字符中表示边界的符号,例如:"^" 、 "$" 、 "\b" 、"\B" 等。
5、捕获组与非捕获组
捕获组:使用小括号( )将一部分正则表达式括起来,可以将匹配到的字符串保存到一个临时变量中,以便后续使用。例如:(\d{4}-\d{2}-\d{2})可以捕获年、月、日。
非捕获组:使用 (?:) 创建的非捕获组,不会将匹配到的字符串保存到临时变量中,但可以作为整体进行匹配。
6、预查
正向肯定预查:使用(?=pat)来创建,其中pat是你希望出现在当前位置之后但不包括在匹配结果中的模式。例如:[a-z](?=\d+)表示确保这些小写字母后面跟着至少一个数字,但数字本身不会被包括在匹配结果中。假设有字符串foo12opr25or3,使用上述示例正则的匹配结果就是:
["foo", "opr", "or"]
负向肯定预查:使用(?!pat)来创建,检查当前位置后面是否不出现特定的模式。如果后面的字符序列不符合指定的模式,则匹配成功;否则,匹配失败。它不会将检查的模式pat匹配出来,仅将其用于条件判断。并且,不会改变匹配过程中的字符位置,即匹配失败后,会立即在当前位置尝试下一次匹配,而不会跳过任何字符。常常用于验证格式。比如:Windows(?!95|98|NT)表达式去匹配Windows 3.1中的Windows,就能匹配成功,因为3.1不在排除列表中,如果用它匹配 Windows 95 或者 Windows 98 就会匹配失败。
正向否定预查:使用(?<=pat)来创建,用于匹配一个位置,该位置的前面不能紧跟模式pat。它不会消耗(匹配)前面的字符,它只用于检查前面的字符是否不满足特定模式。如果不满足(即前面的字符不是指定的模式),则匹配当前位置,并继续向后匹配;如果满足(即前面的字符是指定的模式),则匹配失败。比如:用\b(?<!un)\w+表达式匹配字符串"unhappy, happy, unusual, usual, unique, quick",将匹配将匹配“happy”、“usual”、“quick”,而不会匹配以“un”开头的单词。因为un已经被否定了。再如表达式\b(?<!\d{2}/\d{2}/)\d{4}可以用来排除格式为“MM/DD/YYYY”的日期。
负向否定预查:使用(?<!pat)来定义,它用于匹配一个位置,确保该位置的前面没有紧跟指定的模式 pat。同样的,它不会消耗(即不会包括在匹配结果中)前面的字符,它只是检查前面的字符是否不满足特定模式。如果不满足(即前面的字符不是指定的模式),则匹配当前位置;如果满足(即前面的字符是指定的模式),则匹配失败。例如:表达式 ^(?!.*\berror:\b).*$ 可以匹配一个不以error:结尾的文本。
二、应用场景
正则表达式在多个领域有广泛应用,包括但不限于:
数据验证:验证手机号码,邮箱等字符串是否符合特定的格式。
文本的搜索和提取:从大量文本中查找特定的模式或关键词,提取网页中的特定信息(如链接、标题等)。
文本处理与转换:替换特定的文本模式,清理和格式化文本(如删除特殊字符、转换大小写等)。
变成语言:在代码中处理字符串的复杂需求,如语法检查、日志分析等。
命令行工具:如grep、awk等,支持正则表达式来处理文本。
在WPS编辑器中,常用来匹配表格中的文本是否满足某种格式,例如:身份证号码是否是大陆身份证,还是临时通行证等;也常用来提取特定文本等等。
三、常用正则实例
1、验证电子邮件地址
^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$
2、验证电话号码
^\d{3}-\d{3}-\d{4}$
3、匹配中文字符
[\u4e00-\u9fa5]+
4、匹配url
^(https?://)[^\s/$.?#].[^\s]*$
四、注意点
1、模式复杂度:复杂的正则表达式可能导致性能问题,特别是在处理大量文本时。
2、引擎差异:不同的正则表达式引擎(如 Perl、Python、Java 等)可能在语法和性能上存在差异。
3、可读性:编写正则表达式时,应尽量保持其可读性和可维护性,避免过度复杂。
五、总结
总体而言,正则表达式是一种非常实用的工具。理解和掌握正则表达式,在面对复杂文本时,可以加速处理。例如,通过爬虫获取到网页源码,可以通过正则来获取其中包含的信息。