【上一篇:49.关于字符串的基础知识和一些字符串操作函数】
【下一篇:51.关于模式匹配的一些函数(一)】
本篇适合对正则表达式有一定了解,但基础又不是很好的读者。
在学习正则表达式之前,先学会用两个函数:str_view()和str_view_all(),这两个函数输入字符串和一个正则表达式,返回字符串中匹配到的位置。跟一些测正则表达式的网站相似。
正则匹配:如果一个string符合某种pattern,则该字符串为想要的字符串。
# 只展示第一个匹配
str_view(string, pattern, match = NA)
# 展示所有的匹配
str_view_all(string, pattern, match = NA)
match:TRUE:仅展示模式匹配上的字符串;FALSE:仅展示未模式匹配上的字符串;
NA:模式匹配上和未匹配上的都展示。
通过本篇:
1) 学会区分正则表达式和定义正则表达式的字符串。
2) regex metacharacters(正则元字符,特殊字符,通配符)除了可以用反斜杠转义之外,也可以用字符类表示,后者可读性更好。双引号和单引号不属于元字符。
3) 字符串和正则表达式都用反斜杠来转义一些字符的特殊行为。我们用字符串来表示正则表达式。
4) 正则表达式中的一个反斜杠要用字符串中的四个反斜杠表示。即:
chr<-"a\\b"
str_view(chr,"\\\\")
你的实际字符串是a\b
在R中用string表示的话,需要写成a\\\b,因为string中反斜杠属于特殊字符,需要加一个反斜杠进行转义
writeLines(chr)可以正确打印出你的实际字符串
print函数打印的结果永远是带有转义字符的,且字符串用双引号括起来
你想要匹配chr中的反斜杠,也就是你的实际正则表达式是一个反斜杠
因为反斜杠在正则中也是一个特殊字符,所以在正则中需要加一个反斜杠进行转义
又因为我们用string表示正则表达式,反斜杠在string中也是一个特殊字符
所以要分别对正则表达式中的两个反斜杠加反斜杠进行转义,
最终,我们用string中的四个反斜杠来表示正则表达式中的一个反斜杠
5) 当你的正则表达式中出现单个元字符,比如$
.
|
?
*
+
(
)
[
{
,除了通过加反斜杠的方法进行转义之外,还可以写到中括号中,表示一个字符类。除了这些元字符,像\d
\s
这些转义字符也可以写到中括号中。在有特殊字符的情况下,如何正确地用string表示正则表达式呢?
第一步:明确你想写的正则表达式,此时不用考虑任何转义
如果你想用反斜杠进行转义,则:
第二步:看你的特殊字符在正则中是否需要关闭其特殊功能(即转义),
如果需要,先加上一个反斜杠进行转义。比如:
$在正则中表示结尾锚定,\$表示你要匹配一个真实的$符号
.在正则中表示占位符,匹配除换行符之外的所有字符,\.表示你要匹配一个真实的.符号
|在在正则中表示可选,也就是“或”关系,\|表示你要匹配一个真实的|符号
?在正则中表示前面的字符匹配0次或1次,\?表示你要匹配一个真实的?符号
*在正则中表示前面的字符匹配任意次,\*表示你要匹配一个真实的*符号
+在正则中表示前面的字符匹配1次或多次,\+表示你要匹配一个真实的+符号
()在正则中表示一组字符,\(\)表示你要匹配一对真实的括号,单独使用也要转义
[在正则中表示*****,\[表示你要匹配一个真实的[符号
{在正则中表示*****,\{表示你要匹配一个真实的{符号
------------------------------
\d在正则中表示匹配一个数字,本身已经转义,不需要再加反斜杠
\s在正则中表示匹配任何空白符,如空格、制表符和换行符
------------------------------
第三步:基于第二步的结果,看第二步新形成的字符串中的每个字符是否在string中是特殊字符。
如果是,则再加反斜杠进行转义。
最终用string表示的regex如下:
\\$ \\. \\| \\? \\* \\+ \\( \\) \\[ \\{ \\d \\s
**************************
如果想用字符类的方式进行转义,即用中括号将特殊字符括起来,那结果如下:
[$] [.] [|] [?] [*] [+] [(] [)] [[] [{] [\d] [\s]
6) 一些元字符并不能用字符类的方式转义,比如]
\
^
-
,因为这些字符在字符类(中括号括起)中也有特殊含义。因此必须用反斜杠进行转义。
7) ^
$
^ 在字符类之外表示匹配字符串的开头,在字符类内部表示取反
str_view("babana","^b")
str_view("babana","[^b]")
$ 表示匹配字符串的结尾
8) |
|在字符类之外表示可选,在字符类内部就是一个真正的|字符
在字符类外的时候,|的优先级很低,可以通过加()来明确表示你想要什么,例如:
x<- "abc|def" 匹配abc或def
x<- "ab(c|d)..f" 匹配abcf或abdf
9) 关于模式匹配的次数,也就是一个string只有匹配一个pattern多少次才算匹配上。
5)中讲了三个元字符:?、+、*,可以设置pattern需要匹配多少次。
记忆:?是有或没有的意思,所以是0次或1次;+ :至少匹配一次;*匹配任意次数,即使匹配不到也可以。
****************************************
还有一种指定次数的方法:
{n} : 匹配n次,精确的
{n,}:至少匹配n次
{,m}:最多匹配m次
{n,m}:匹配次数>=n且<=m
记忆:想象成左闭区间、右闭区间、左闭右闭区间
指定次数的方式默认都是贪婪匹配,例如:
test<-"ABCCCCDEF"
str_view(test,"C{2,4}") 匹配上的部分是CCCC
也就是将最长的匹配区域作为最终的匹配区域
str_view(test,"C{2,4}?") 匹配上的部分是CC
也就是?将匹配改为非贪婪式的,即认为第一个匹配上的最短区域为最终匹配区域
这是正则匹配的高级特性
10)正则匹配中的分组和反引用。8)中讲括号作为消除复杂表达式歧义的一种方法。括号还可以创建一个编号的捕获组,捕获组将与正则表达式部分匹配的字符串部分存储在括号内。您可以引用与之前匹配的具有反向引用的捕获组(如\1、\2等)相同的文本。
正则匹配中的分组和反引用
今天终于有机会好好了解一下正则,很基础,但很有用。之前看过很多教程,但大多只是告诉你怎么用,却没有一些原理类的说明。当时会用,过后就忘。所以读一本系统性的书还是很重要的。
网友评论