目录
2.1.1 基础正则表达模式
正则表达式是区分大小写的;小写/s/与大写/S/是不同的(/s/匹配小写s而不是大写字母S)
[ ]方括号内的字符串指定要匹配的字符的分离。例如,图2.2表示模式/[WW] /匹配包含w或W的模式。
问号操作符/?/,他表示“前面的字符出现或不出现”,如图2.5所示。
问号?操作符表示前面的表达式是可选的
使用通配符.来表示任何单一字符
通配符经常与星号一起使用表示“任何字符串”。例如,我们想找aardvark出现两次的句子。我们可以用正则表达式/aardvark.*aardvark/。
锚点是将正则表达式锚定到字符串中特定位置的特殊字符。最常见的锚点是插入符号^和美元符号$。插入符号匹配一行的开头。模板
/^The/
用于匹配以The开头的行。因此,插入符号有三种用法:
1)匹配一行的开头;
2)在正方括号内表示一个否定;
3)表示插入符号本身。大家此时可以思考一下grep或python在什么情况下能够判断插入符起的作用?。
美元符号
匹
配
一
行
的
结
尾
。
因
此
,
模
板
␣
匹配一行的结尾。 因此,模板␣
匹配一行的结尾。因此,模板␣是用于匹配行末是空格的句子。/^The dog.$/匹配只包含The dog.的一行。(我们必须使用反斜杠,因为我们想要句号而不是通配符。)
这里还有另外两个锚:
\b匹配一个单词边界,\B匹配一个非边界。
因此,/\bthe\b/匹配单词the而不是单词other。
2.1.2 分离,分组和优先级
一个操作符可以优先于另一个操作符,有时我们还会使用括号来凸显我们的意思,这就形成了正则表达式的运算符优先级层次。下表给出了RE运算符从最高优先级到最低优先级的顺序。
因此,由于操作符具有比序列高的优先级,/the/匹配theeee,而不是匹配thethe。由于序列比分离具有更高的优先级,/the|any/匹配the或者any,但不匹配theny。
2.1.3 一个简单的例子
/the/
/[tT]he/
/\b[tT]he\b/
/[ˆa-zA-Z][tT]he[ˆa-zA-Z]/
/(ˆ|[ˆa-zA-Z])[tT]he([ˆa-zA-Z]|$)/
2.1.4 更多操作符
图2.8显示了常用范围的别名
可计数的RE总结在图2.9中。
某些字符通过使用反斜杠转义后表达特殊含义,比如\n表示另起一行,\t表示tab。另外,特殊字符在表达字符原本含义时需要反斜杠(\)进行转义。
2.1.5 一个更复杂的例子
任何超过6 GHz和500 GB的磁盘空间小于1000美元的机器
价格:
/$[0-9] +/
/$[0-9]+\.[0-9][0-9]/
/(ˆ|\W)$[0-9]+(\.[0-9][0-9])?\b/
/(ˆ|\W)$[0-9]{0,3}(\.[0-9][0-9])?\b/
磁盘空间:
/\b[0-9]+(\.[0-9]+)? *(GB|[Gg]igabytes?)\b/
2.1.6 正则表达式替换、捕获组和ELIZA
正则表达式的一个重要用途是替换。
s/regexp1/pattern/
的正则表达式,来完成一个字符串替换另一个字符串的功能,例如
s/colour/color/
假如我们想将文本中所有的数字前后加上尖括号<>,如将the 35 boxes改为the <35> boxes
使用圆括号()将第一个模板括起来,并在第二个模式中使用数字运算符1来回溯。这就是它的样子:
s/([0-9]+)/<\1>/
括号和数字运算符还可以指定某个字符串或表达式必须在文本中出现两次。例如,假设我们要检索“the Xer they were, the Xer they will be ”这种句子,约定两个X代表形同的字符串。我们可以这样做:用括号运算符将第一个X括起来,然后用数字运算符1替换第二个X,如下:
/the (.*)er they were, the \1er they will be/
在这里,\1将被替换为第一个匹配项匹配的任何字符串。
使用这个模板可以匹配The bigger they were, the bigger they will be ,
但匹配不到The bigger they were, the faster they will be。
使用圆括号将模式存储在内存中称为捕获组。每次使用捕获组(即圆括号包围模板)时,捕获组中的模板匹配到的结果将存储在一个数字编号寄存器中,通过“\数字”提取出来。
如果有两个捕获组,那么\2代表第二个捕获组匹配到的内容。
因此 /the (.)er they (.), the \1er we \2/
将匹配到
The faster they ran, the faster we ran,
但不能匹配
The faster they ran, the faster we ate。
同样,第三捕获组存储在\3,第四个是\4,等等。
因此,括号在正则表达式中具有双重功:
它们用于分组或优先级,即指定操作符的顺序;
另一个作用是,使用寄存器捕获某些东西。
有时我们可能希望使用圆括号用于进行分组,但不想使用捕获组的模式。在这种情况下,我们使用非捕获组,形式是在左圆括号后面加上?:即(?:模板)。例如
/(?:some|a few) (people|cats) like some \1/
将匹配到some cats like some cats,但匹配不到 some people like some a few。
ELIZA是通过一系列或级联的正则表达式替换来工作的,每个正则表达式替换和改变输入行的某些部分。首先是将my替换为YOUR,将I’m替换为YOU ARE。然后替换输入中匹配到的内容。下面是一些例子:
2.1.7 预测断言
预测断言:在文本中只检查是否匹配,但不移动匹配游标。
预测断言使用了
(?
语法,类似的语法我们在非捕获组的定义中看到过。
操作符
(?= pattern)
表示如果模板能匹配上则该断言返回true,但为零宽度,即匹配指针不前进。
操作符
(?! pattern)
只有在不匹配时返回true,但同样是零宽度,不前进光标。
在一些复杂的模板中,要排除一个特殊的情况时,通常使用否定的断言。
例如,假设我们查找一个开头单词不是“Volcano ”的句子。我们可以用否定的预测断言来做到这一点:
/ˆ(?!Volcano)[A-Za-z]+/
参考:
https://blog.youkuaiyun.com/hln24477932/article/details/81698427