DataWhale数据分析|Task3 正则表达式学习
本文主要参考正则表达式——菜鸟教程
学习要求
知道正则表达式的匹配方式,以及常用的正则表达式写法
学习目标
- 了解什么是正则表达式(WHAT)
- 了解为什么要用正则表达式(WHY)
- 了解怎么使用正则表达式(HOW)
学习流程
1. 什么是正则表达式
正则表达式(Regular Expression)是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为"元字符")。
正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。
2. 为什么要用正则表达式
首先给出网友的观点:
(来源:百度知道:正则表达式有哪些优缺点)
我觉得最大的缺点有以下几个方面:
1.正则表达式只适合匹配文本字面,不适合匹配文本意义:像匹配url,email这种纯文本的字符就很好,但比如匹配多少范围到多少范围的数字,如果你这个范围很复杂的话用正则就很麻烦。或者匹配html,这个是很多人经常遇到的,写一个复杂匹配html的正则很麻烦,不如使用针对特定意义的处理器来处理(比如写语法分析器,dom分析器等)
2.容易引起性能问题:像.*这种贪婪匹配符号很容易造成大量的回溯,性能有时候会有上百万倍的下降,编写好的正则表达式要对正则引擎执行方式有很清楚的理解才可以
3.正则的替换功能较差:甚至没有基本的截取字符串或者把首字母改变大小写的功能,这对于url重写引擎有时候是致命的影响
但是也有优点:只要熟练应用正则表达式,而且匹配的目标是纯文本,那么相比于写分析器来说,正则可以更快速的完成工作。还有在捕获字符串的能力,正则也可以很好的完成工作,比如截取url的域名或者其他的内容等等
优点强大应用广泛缺点难学可读性差。
(来源:知乎:正则表达式有哪些优缺点?)
“Let’s say you have a problem, and you decide to solve it with regular
expressions. Well, now you have two problems.““
比如说,你想解决一个问题,然后你决定用正则表达式来解决。那么好,你现在有两个问题要解决了。“
缺点:1 大工程中性能让人捉急。2 难写(当然应付小任务的话夏几吧写也是可以的)。3 难读。4 如果源码进行了微调,那就得重新搞一下。
优点:1 好学,一招鲜 不需要单独学习xpath css html之类。2 适用范围广
例如对于非结构性文档(例如有些网站是用文本集传输数据 并用js切割、渲染的以优化性能)这时选择器就跪了 但是正则万能无敌。
正则这货,同样的问题同样的方案在不同的环境,要想同样有效,那是不太可能的。
唉,总是要重写调试。当然环境一样就不存在这个问题。
另外,稍微复杂一点,别人没法读,也就没法改,所以一有处理对象变化,就得再写一个。
要是,再再复杂一点,自己也是一趟过,再来第二趟,那还不如重写。
1、灵活性,逻辑性,功能性非常强大
2、可以用少量的代码简单的方式来匹配复杂的内容
综上可以看出,正则表达式的优势在于适用范围广,功能强大,受广泛支持;
当然,缺点也很明显,由于本身的贪婪匹配原因,在大型项目中很容易引起性能问题;此外,由于其复杂的编写方式,难读、难写,可重用性差,也是让人头痛不已的点。
根据以上观点,我的想法是:对于复杂度较低的字符串匹配,或者对性能要求不高、功能较长时间不会改变的话,正则表达式是很好的选择。
3. 怎么使用正则表达式
1) 字符
普通字符: 大写和小写字母、所有数字、所有标点符号和一些其他符号
[ABC]
匹配[...]
中的所有字符,例如[aeiou]
匹配字符串"google runoob taobao"
中所有的a
e
i
o
u
字母。[^ABC]
匹配除了[...]
中字符的所有字符,例如[^aeiou]
匹配字符串"google runoob taobao"
中除了a
e
i
o
u
字母的所有字母。[A-Z]
[A-Z]
表示一个区间,匹配所有大写字母,[a-z]
表示所有小写字母。.
匹配除换行符(\n、\r)
之外的任何单个字符,相等于[^\n\r]
。\s \S
匹配所有。\s
是匹配所有空白符,包括换行,\S
非空白符,包括换行。\w
匹配字母、数字、下划线。等价于[A-Za-z0-9_]
特殊字符: 有特殊含义的字符
$
匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性,则$
也匹配\n
或\r
。要匹配$
字符本身,请使用\$
。(
)
标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配(
和)
,请使用\(
和\)
。*
匹配前面的子表达式零次或多次。要匹配*
字符,请使用\*
。+
匹配前面的子表达式一次或多次。要匹配+
字符,请使用\+
。.
匹配除换行符 \n 之外的任何单字符。要匹配.
,请使用\.
。[
标记一个中括号表达式的开始。要匹配[
,请使用\[
。?
匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配?
字符,请使用\?
。\
将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如,n
匹配字符n
,而\n
匹配换行符。序列\\
匹配\
,而\(
则匹配(
。^
匹配输入字符串的开始位置,除非在方括号表达式中使用,当该符号在方括号表达式中使用时,表示不接受该方括号表达式中的字符集合。要匹配^
字符本身,请使用\^
。{
标记限定符表达式的开始。要匹配{
,请使用\{
。|
指明两项之间的一个选择。要匹配|
,请使用\|
。
限定符: 限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。
*
匹配前面的子表达式零次或多次。例如,zo*
能匹配z
以及zoo
。*
等价于{0,}
。+
匹配前面的子表达式一次或多次。例如,zo+
能匹配zo
以及zoo
,但不能匹配z
。+
等价于{1,}
。?
匹配前面的子表达式零次或一次。例如,do(es)?
可以匹配do
、does
中的does
、doxy
中的do
。?
等价于{0,1}
。{n}
n
是一个非负整数。匹配确定的 n 次。例如,o{2}
不能匹配Bob
中的o
,但是能匹配food
中的两个o
。{n,}
n 是一个非负整数。至少匹配n 次。例如,o{2,}
不能匹配Bob
中的o
,但能匹配foooood
中的所有o
。o{1,}
等价于o+
。o{0,}
则等价于o*
。{n,m}
m
和n
均为非负整数,其中n <= m
。最少匹配 n 次且最多匹配 m 次。例如,o{1,3}
将匹配fooooood
中的前三个o
。o{0,1}
等价于o?
。请注意在逗号和两个数之间不能有空格。
定位符: 定位符使您能够将正则表达式固定到行首或行尾。
^
匹配输入字符串开始的位置。如果设置了 RegExp 对象的 Multiline 属性,^
还会与\n
或\r
之后的位置匹配。$
匹配输入字符串结尾的位置。如果设置了 RegExp 对象的 Multiline 属性,$
还会与\n
或\r
之前的位置匹配。\b
匹配一个单词边界,即字与空格间的位置。\B
非单词边界匹配。
标记符: 标记符也称为修饰符,用于指定额外的匹配策略。
标记不写在正则表达式里,标记位于表达式之外,格式为:/pattern/flags
,例如:/runoob/gi
,查找所有匹配项, 且不区分大小写
i
ignore,将匹配设置为不区分大小写。
g global,全局匹配 查找所有的匹配项。
m
multi-line , 多行匹配,使边界字符 ^
和 $
匹配每一行的开头和结尾,PS: 是多行,而不是整个字符串的开头和结尾。
s
特殊字符.
中包含换行符 \n
默认情况下的.
是 匹配除换行符 \n
之外的任何字符,加上 s
修饰符之后, . 中包含换行符 \n
。
2)运算符优先级
正则表达式从左到右进行计算,并遵循优先级顺序,这与算术表达式非常类似。
相同优先级的从左到右进行运算,不同优先级的运算先高后低。下表从最高到最低说明了各种正则表达式运算符的优先级顺序:
运算符 | 描述 | 级别 |
---|---|---|
\ | 转义符 | 1 |
() , (?:) , (?=) , [] | 圆括号和方括号 | 2 |
* , + , ? , {n} , {n,} , {n,m} | 限定符 | 3 |
^ , $ , \任何元字符 、任何字符 | 定位点和序列(即:位置和顺序) | 4 |
| | 替换,"或"操作 ;| 字符具有高于替换运算符的优先级,使得m|food 匹配m 或food 。若要匹配mood 或food ,请使用括号创建子表达式,即(m|f)ood | 5 |
参考文献:
[1]. 正则表达式——菜鸟教程