【精】【入门篇】js正则表达式
前言
最近有了点时间,就回头看了一下《学习正则表达式》这本书。怎么说呢,这本书适合从零开始学习正则表达式或者有一点基础但是想要加强这方面能力的读者。这本书的风格是“实践出真知”,使用归纳方式讲述, 也就是说, 会从特例讲起, 最终归结到一般情况。不会先陈述观点, 然后举例, 而是先为大家展示示例, 然后归纳出一般性结论。所以刚开始的话还是有点不习惯这种风格。
吐槽只是皮一下而已啦,这本是还是可以的,感兴趣的小伙伴不妨去看看,书本不厚,也就140页左右。【附上pdf】
正则表达式
1.为什么使用正则表达式?
典型的搜索和替换操作要求您提供与预期的搜索结果匹配的确切文本。虽然这种技术对于对静态文本执行简单搜索和替换任务可能已经足够了,但它缺乏灵活性,若采用这种方法搜索动态文本,即使不是不可能,至少也会变得很困难。
通过使用正则表达式,可以:
- 测试字符串内的模式。
例如,可以测试输入字符串,以查看字符串内是否出现电话号码模式或信用卡号码模式。这称为数据验证。 - 替换文本。
可以使用正则表达式来识别文档中的特定文本,完全删除该文本或者用其他文本替换它。 - 基于模式匹配从字符串中提取子字符串。
可以查找文档内或输入域内特定的文本。
2.什么是正则表达式
“正则表达式是描述一组字符串特征的模式, 用来匹配特定的字符串。 ”
——Ken Thompson
正则表达式是对字符串(包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为“元字符”))操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。
——百度百科
定义千万条,真理就一条。简单来讲,正则表达式描述了一个规则,通过这个规则可以匹配一类字符串。这里需要注意一下,正则表达式是一个规则。
这里有个辅助理解正则表达式的一个工具,Regexper 。
上面这个示例展示的是利用正则表达式匹配手机号码,正则表达式为/^1[34578][0-9]{9}$/,从生成的辅助图可以看出,这个正则的规则是检测以1开头,第二位为3、4、5、7、9 其中一个,以9位(本身1次加重复8次)0-9数字结尾的的字符串。有了这个工具,可以很形象的帮助我们理解正则表达式。是不是很赞?好了好了,该回归正题了。该铺垫的已经铺垫了,改举例的也举例了,那么接下来就该讲讲最基本的语法啦。come on!
3.语法
正则表达式是由普通字符(例如字符 a 到 z)以及特殊字符(称为“元字符”)组成的文字模式。模式描述在搜索文本时要匹配的一个或多个字符串。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。
3.1 普通字符
普通字符包括没有显式指定为元字符的所有可打印和不可打印字符。这包括所有大写和小写字母、所有数字、所有标点符号和一些其他符号。
比如说正则表达式/is/ 匹配字符串'is',表达式里面的字符串is就是普通字符'i'和's'构成。
非打印字符如下:
3.2 常见标准字符
当然,正则表达式里面的标准字符不止这些,由于本篇是入门篇,一些不常见或者比较复杂的字符符号在这里就不涉及,想要了解的可以随时问度娘。
3.3 特殊字符(称为“元字符”)
许多特殊字符要求在试图匹配它们时特别对待。若要匹配这些特殊字符,必须首先使字符"转义",即,将反斜杠字符 (\) 放在它们前面。要匹配 $ 字符本身,使用 \$。要匹配 |,使用 \|。要匹配\,使用 \\ 。
3.3.1 修饰符
修饰符与其他语法特殊,字面量方法声名的时候放到//后,构造函数声明的时候,作为第二个参数传入。整个正则表达式可以理解为/正则表达式主体/修饰符(可选)。
常见写法比如:regex=/x/g、regex=/xXX/i 等,也可以多个修饰符同时使用,比如regex=/xXX/ig,表示不区分大小写并且全局匹配。
3.3.2 选择和分组符
用圆括号将所有选择项括起来,即完全匹配,相邻的选择项之间用|分隔,即多选一。但用圆括号会有一个副作用,是相关的匹配会被缓存,此时可用?:放在第一个选项前来消除这种副作用。
上面栗子reg=/x|y/,表示匹配字符x或y。
上面说到圆括会把相关的匹配缓存,什么意思呢?在正则里面,对一个正则表达式模式或部分模式两边添加圆括号将导致相关匹配存储到一个临时缓冲区中,所捕获的每个子匹配都按照在正则表达式模式中从左到右出现的顺序存储。缓冲区编号从 1 开始,最多可存储 99 个捕获的子表达式。每个缓冲区都可以使用 '\n' 访问,其中 n 为一个标识特定缓冲区的一位或两位十进制数。这就是正则里面的反向引用。
关于反向?
正则表达式中有前瞻(Lookahead)和后顾(Lookbehind)的概念,需要注意一点,正则表达式中的前和后和我们一般理解的前后有点不同。一段文本,我们一般习惯把文本开头的方向称作“前面”,文本末尾方向称为“后面”。但是对于正则表达式引擎来说,因为它是从文本头部向尾部开始解析的(可以通过正则选项控制解析方向),因此对于文本尾部方向,称为“前”,因为这个时候,正则引擎还没走到那块,而对文本头部方向,则称为“后”,因为正则引擎已经走过了那一块地方。
比如正则表达式/(abc)d\1/匹配 abcabcd abcabcdabccca ,(abc)d\1可以匹配字符串abcdabc,即\1表示把获取到的第一组再匹配一次。
3.3.3 限定符(量词)
限定字符又叫量词,是用于表示匹配的字符数量的,即一个给定组件必须要出现多少次才能满足匹配。有*或+或?或{n}或{n,}或{n,m}共6种。
3.3.4 定位符
定位符使您能够将正则表达式固定到行首或行尾。它们还使您能够创建这样的正则表达式,这些正则表达式出现在一个单词内、在一个单词的开头或者一个单词的结尾。
定位符用来描述字符串或单词的边界,^和$分别指字符串的开始与结束,\b描述单词的前或后边界,\B表示非单词边界。
reg=/1234/能匹配字符串0123456,而reg=/^1234/不可以,因为这里加了定位符,要求必须是以1开头的字符串,比如匹配12345。
\b匹配一个边界。所以如果使用正则表达式/\bword\b/ 匹配"word"、"a word"、"a word D"都是可以的。想一想这个字符串"a word."能匹配成功吗?
答案是可以的。有人可能就有疑问说,\b匹配的是不是字边界吗,word后面直接接了一个点,而不是空格或者没有其他东西。哈哈,其实你们都理解错了。\b匹配的这个边界,指[a-zA-Z_0-9]之外的字符,即不是\w字符,由于.不属于\w字符,所以就能够匹配成功。大家可以自己试试看,利用网上的正则表达式测试工具自己动手试一下,比如 https://www.regexpal.com/。
注意:不能将限定符与定位点一起使用。由于在紧靠换行或者字边界的前面或后面不能有一个以上位置,因此不允许诸如 ^* 之类的表达式。
3.3.5 自定义字符集合
方括号[ ]表示字符集合,即[ ]表示自定义集合,用[ ]可以匹配方括号里的任意一个字符。reg=/[aeiou]/匹配'a','e','i','o','u'任意一个字符。/[0-9]/则表示匹配数字0-9之中其中一个,/[a-zA-Z]/则匹配所有大小写字母中的一个字母。/[a-zA-Z0-9_]/则等效于\w。
但是,特殊字符(除了小尖角'^'和中划线'-'外)被包含到方括号中,就会失去特殊意义,只代表其字符本身。reg=/[abc+?]/匹配'a','b','c'任意一个字符或者'+','?',即包含在自定义集合中的特殊字符'+','?'失去了特殊含义,只表示其字符本身的意思。
特殊字符小尖角'^',原本含义是匹配字符串的开始位置,如果包含在自定义集合[ ]中,则表示取反的意思。比如:reg=/[^aeiou]/匹配'a','e','i','o','u'之外的任意一个字符。
中划线'-',在自定义集合[ ]中,表示“范围”,而不是字符'-'本身,reg=/[a-z]/,匹配从a到z中26个字母的任意一个。
4 优先级
正则表达式从左到右进行计算,并遵循优先级顺序,这与算术表达式非常类似。
相同优先级的从左到右进行运算,不同优先级的运算先高后低。下表从最高到最低说明了各种正则表达式运算符的优先级顺序:
总结
正则表达式虽然比较烦琐,但它是强大的,学会之后的应用会让你除了提高效率外,会给你带来绝对的成就感。
正则表达式远不止这里所涉及到的,所以这里只是入门。俗话说师傅领进门,修行看个人。加油吧,骚年。保持一颗学习的心❤!
附:正则表达式速查表:https://www.jb51.net/tools/regexsc.htm