55分钟学会正则表达式(来自Github)(3)

特别提示:统一字符集中包含除了0至9之外的更多数字字符,同样的,也包含更多的空字符和字母字符。实际使用正则表达式时,请仔细查看相关文档。

练习

简化正则表达式 [0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9].

答案

\d\d\d\d-\d\d-\d\d.

重复

在字符或字符集之后,你可以使用{ }大括号来表示重复

正则表达式a{1}与a意思相同,都表示匹配字母a

a{3}表示匹配字符串“aaa”

a{0}表示匹配空字符串。从这个正则表达式本身来看,它毫无意义。如果你对任何文本执行这样的正则表达式,你可以定位到搜索的起始位置,即使文本为空。

a\{2\}表示匹配字符串“a{2}”

在字符类中,大括号没有特殊含义。[{}]表示匹配一个左边的大括号,或者一个右边的大括号

练习

简化下面的正则表达式

z.......z

\d\d\d\d-\d\d-\d\d

[aeiou][aeiou][aeiou][aeiou][aeiou][aeiou]

[bcdfghjklmnpqrstvwxyz][bcdfghjklmnpqrstvwxyz][bcdfghjklmnpqrstvwxyz][bcdfghjklmnpqrstvwxyz][bcdfghjklmnpqrstvwxyz][bcdfghjklmnpqrstvwxyz][bcdfghjklmnpqrstvwxyz][bcdfghjklmnpqrstvwxyz][bcdfghjklmnpqrstvwxyz][bcdfghjklmnpqrstvwxyz]

答案

z.{7}z

\d{4}-\d{2}-\d{2}

[aeiou]{6}

[bcdfghjklmnpqrstvwxyz]{10}

注意:重复字符是没有记忆性的,比如[abc]{2}表示先匹配”a或者b或者c”,再匹配”a或者b或者c”,与匹配”aa或者ab或者ac或者ba或者bb或者bc或者ca或者cb或者cc“一样。[abc]{2}并不能表示匹配”aa或者bb或者cc“

指定重复次数范围

重复次数是可以指定范围的

x{4,4}与x{4}相同

colou{0,1}r表示匹配colour或者color

a{3,5}表示匹配aaaaa或者aaaa或者aaa

注意这样的正则表达式会优先匹配最长字符串,比如输入 I had an aaaaawful day会匹配单词aaaaawful中的aaaaa,而不会匹配其中的aaa。

重复次数是可以有范围的,但是有时候这样的方法也不能找到最佳答案。如果你的输入文本是I had an aaawful daaaaay那么在第一次匹配时,只能找到aaawful,只有再次执行匹配时才能找到daaaaay中的aaaaa.

重复次数的范围可以是开区间

a{1,}表示匹配一个或一个以上的连续字符a。依然是匹配最长字符串。当找到第一个a之后,正则表达式会尝试匹配尽量多个的连续字母a。

.{0,}表示匹配任意内容。无论你输入的文本是什么,即使是一个空字符串,这个正则表达式都会成功匹配全文并返回结果。

练习

使用正则表达式找到双引号。要求输入字符串可能包含任意个字符。

调整你的正则表达式使得在一对双引号中间不再包含其他的双引号。

答案

".{0,}", 然后 "[^"]{0,}".

关于重复的转义字符

?与{0,1}相同,比如,colou?r表示匹配colour或者color

*与{0,}相同。比如,.*表示匹配任意内容

+与{1,}相同。比如,\w+表示匹配一个词。其中”一个词”表示由一个或一个以上的字符组成的字符串,比如_var或者AccountName1.

这些是你必须知道的常用转义字符,除此之外还有:

\?\*\+ 表示匹配字符串”?*+”

[?*+]表示匹配一个问号,或者一个*号,或者一个加号

练习

简化下列的正则表达式:

".{0,}" and "[^"]{0,}"

x?x?x?

y*y*

z+z+z+z+

答案

".*" and "[^"]*"

x{0,3}

y*

z{4,}

练习

写出正则表达式,寻找由非字母字符分隔的两个单词。如果是三个呢?六个呢?

\w+\W+\w+, \w+\W+\w+\W+\w+, \w+\W+\w+\W+\w+\W+\w+\W+\w+\W+\w+.

下文中,我们将简化这个正则表达式。

非贪婪匹配

正则表达式 “.*” 表示匹配双引号,之后是任意内容,之后再匹配一个双引号。注意,其中匹配任意内容也可以是双引号。通常情况下,这并不是很有用。通过在句尾加上一个问号,可以使得字符串重复不再匹配最长字符。

\d{4,5}?表示匹配\d\d\d\d或者\d\d\d\d\d。也就是和\d{4}一样

colou??r与colou{0,1}r相同,表示找到color或者colour。这与colou?r一样。

“.*?”表示先匹配一个双引号,然后匹配最少的字符,然后是一个双引号,与上面两个例子不同,这很有用。

选择匹配

你可以使用|来分隔可以匹配的不同选择:

cat|dog表示匹配”cat”或者”dog”

red|blue|以及red||blue以及|red|blue都表示匹配red或者blue或者一个空字符串

a|b|c与[abc]相同

cat|dog|\|表示匹配”cat”或者”dog”或者一个分隔符”|“

[cat|dog]表示匹配a或者c或者d或者g或者o或者t或者一个分隔符“|”

练习

简化下列正则表达式:

s|t|u|v|w

aa|ab|ba|bb

[abc]|[^abc]

[^ab]|[^bc]

[ab][ab][ab]?[ab]?

答案

[s-w]

[ab]{2}

.

[^b]

[ab]{2,4}

练习

使用正则表达式匹配1到31之间的整数,[1-31]不是正确答案!

这样的正则表达式不唯一. [1-9]|[12][0-9]|3[01] 是其中之一。

分组

你可以使用括号表示分组:

通过使用 Mon|Tues|Wednes|Thurs|Fri|Satur|Sun)day 匹配一周中的某一天

(\w*)ility 与 \w*ility 相同。都是匹配一个由”ility”结尾的单词。稍后我们会讲解,为何第一种方法更加有用。

\(\)<script type='math/tex'></script>表示匹配一对括号。

[()]表示匹配任意一个左括号或者一个右括号

练习

在《时间机器中》找到一对括号中的内容,然后通过修改正则表达式,找到不含括号的内容。

答案

\(.*\)<script type='math/tex'>.*</script>. 然后是, \([^()]*\)<script type='math/tex'>[^()]*</script>.

分组可以包括空字符串:

(red|blue)表示匹配red或者blue或者是一个空字符串

abc()def与abcdef相同

你也可以在分组的基础上使用重复:

(red|blue)?与(red|blue|)相同

\w+(\s+\w+)表示匹配一个或多个由空格分隔的单词

练习

简化正则表达式 \w+\W+\w+\W+\w+ 以及 \w+\W+\w+\W+\w+\W+\w+\W+\w+\W+\w+.

答案

\w+(\W+\w+){2}, \w+(\W+\w+){5}.

单词分隔符

在单词和非单词之间有单词分隔符。记住,一个单词\w是[0-9A-Za-z_],而非单词字符是\W(大写),表示[^0-9A-Za-z_].

在文本的开头和结尾通常也有单词分隔符。

在输入文本it's a cat中,实际有八个单词分隔符。如果我们在cat之后在上一个空格,那就有九个单词分隔符。.

\b表示匹配一个单词分隔符

\b\w\w\w\b表示匹配一个三字母单词

a\ba表示匹配两个a中间有一个单词分隔符。这个正则表达式永远不会有匹配的字符,无论输入怎样的文本。

单词分隔符本身并不是字符。它们的宽度为0。下列正则表达式的作用不同

(\bcat)\b

(\bcat\b)

\b(cat)\b

\b(cat\b)

练习

在词典中找到最长的单词。

答案

在尝试之后发现,\b.{45,}\b可以在字典中找到最长单词

换行符

一篇文本中可以有一行或多行,行与行之间由换行符分隔,比如:

Line一行文字

Line break换行符

Line一行文字

Line break换行符

Line break换行符

Line一行文字

注意,所有的文本都是以一行结束的,而不是以换行符结束。但是,任意一行都可能为空,包括最后一行。

行的起始位置,是在换行符和下一行首字符之间的空间。考虑到单词分隔符,文本的起始位置也可以当做是首行位置。

最后一行是最后一行的尾字符和换行符之间的空间。考虑到单词分隔符,文本的结束也可以认为是行的结束。

那么新的格式表示如下:

Start-of-line, line, end-of-line

Line break

Start-of-line, line, end-of-line

Line break

Line break

Start-of-line, line, end-of-line

基于上述概念:

^表示匹配行的开始位置

$表示匹配行的结束位置

^&表示一个空行

^.*& 表示匹配全文内容,因为行的开始符号也是一个字符,"."会匹配这个符号。找到单独的一行,可以使用 ^.*?$

\^\$表示匹配字符串“^$”

[$]表示匹配一个$。但是,[^]不是合法的正则表达式。记住在方括号中,字符有不同的特殊含义。要想在方括号内匹配^,必须用[\^]

与字符分隔符一样,换行符也不是字符。它们宽度为0.如下所示的正则表达式作用不同:

(^cat)$

(^cat$)

^(cat)$

^(cat$)

练习

使用正则表达式在《时间机器》中找到最长的一行。

答案

使用正则表达式^.{73,}$可以匹配长度为73的一行

文本分界

在很多的正则表达式实现中,将^和$作为文本的开始符号和结束符号。

还有一些实现中,用\A和\z作为文本的开始和结束符号。

捕捉和替换

从这里开始,正则表达式真正体现出了它的强大。

捕获组

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wypdpg.html