可能是最好的正则表达式的教程笔记了吧...

笔记是由油管的@The Coding Train老师发布系列教程。 因为正则我自己看了很多次,但是很快又忘记。所以为了彻底搞懂,一边学习一边记笔记,以给别人讲课的方式记笔记,我自己的印象会更深,所以就有了以下内容。 小白的晋级路在个人github会持续更新哦: 传送门,欢迎star

正则表达式

1.1. 基本语法

通过一张图表来对正则表达式的基本进行一个回顾

single char quantifiers(数量) position(位置)
\d 匹配数字 * 0个或者更多 ^一行的开头
\w 匹配word(数字、字母) + 1个或更多,至少1个 $一行的结尾
\W 匹配word(数字、字母) ? 0个或1个,一个Optional \b 单词"结界"(word bounds)
\s 匹配white space(包括空格、tab等) {min,max}出现次数在一个范围内  
\S 匹配white space(包括空格、tab等) {n}匹配出现n次的  
. 匹配任何,任何的字符    

1.1.1. single char

假设你有一段字符如下:

字符

 

  • \w

将匹配所有word,当然,() - 等字符除外

  • \w\w\w

发现匹配的有'These are some phone numbers ...' 注意正则表达式是匹配一个连续串的规则,所以可以看到三个字母的单词可以匹配到,6个单词的也可以匹配到。

  • \s\s

匹配到一行中连续两个空格

quantifiers

假设我们有这一段话:

The colors of the rainbow have many colours 
and the rainbow does not  have a single colour.
复制代码

我们想把所有的颜色找出来colors colours colour

答案 colou?rs? 嗯,看起来很简单,很方便。


好了,现在想要匹配一行中的4个数字,或者一行中的5个字母等,这时候用quantifiers就非常方便了。

我现在想找5个字母组成的单词

  • \w{5} 这样可以吗?嗯..不行的,看下它匹配的内容,如下: 'These are some phone numbers 915-555-1234...' 的确,我们模板给的很简单,它只找一行中,连续出现5个字母的序列。所以现在改进一下好了

  • \w{5}\s 为了能找到单词,所以我希望5个字母后,跟一个空格的序列,这样应该可以了吧,看下匹配情况: 'Theseare some phonenumbers915-555-1234...' 嗯,是的,只有目前这些方法,是做不到的。 所以,我们需要第三个工具 "position"

1.1.2. position

回到刚才的问题之前,先熟悉下^ $\b

This is somthing
is about
a blah
words
sequence of words
Hello and
GoodBye and 
Go gogo!
复制代码

来看下各种正则所匹配的内容

  • \w+ 这个应该毫无疑问,匹配所有的words

  • ^\w+ 多了一个^,这样子,就只能匹配到每一行开头的单词了This is a words sequence Hello GoodBye Go

  • \w+$ 这样就能匹配到每行的最后一个字母

回到刚才的问题

现在想找5个字母组成的单词

就变得很简单了,使用单词结界符\b

答案就是\b\w{5}\b

1.1.3. 找个电话号码吧

最后,找一个刚才出现的电话号123-456-1231

用以上最基本的正则方法就是 \d{3}-\d{3}-\d{4},这样就找到了。 但是有的时候,电话号码是123.456.1234 或者 (212)867-4233的结构怎么办呢?

正则表达式中的或者其他表达方式,下面一一来介绍。

1.2. 字符分类(char class)

前面记录了最基本的方法,接下来说一下分类符[]

这个符号用来表示逻辑关系,比如[abc]表示a或者b或c.[-.]表示符号-或者.号(注意这里,在[]中的.号代表的就是这个符号,但是如果在其外面,表示个匹配所有。 所以如果不在[]之中,想要匹配'.',就要通过转意符号\.)

1.2.1. 分类的简单应用

字符序列:

The lynk is quite a link don't you think? l nk l(nk
复制代码

正则表达式: l[yi (]k

结果:

lynk  link  l nk   l(nk
复制代码

很容易理解的,就是表达逻辑。

1.2.2. 匹配所有可能的电话号码

好了,现在回到之前遗留的问题,有以下字段,请匹配所有可能的电话号码:

These are some phone numbers 915-134-3122. Also,
you can call me at 643.123.1333 and of course,
I'm always reachable at (212)867-5509
复制代码

好的,一步一步来,刚才我们使用\d{3}-\d{3}-\d{4}匹配了连字符的情况。现在我们可以很轻松的把.这种情况加进去了

第一步: \d{3}[-.]\d{3}[-.]\d{4}

第二步: 为了能够匹配括号,可以使用?来,因为这是一个option选择。所以最后就成了

\(?\d{3}[-.)]\d{3}[-.]\d{4}

这里还是要说明,在[]中,特殊字符不需要转义,可以直接使用,比如[.()],但是在外面,是需要转义的\( \.

1.2.3. []的特殊语法

刚才介绍了最简单和基本的功能,但是有些特殊的地方需要注意

  1. -连接符不是第一个字符时 [-.]的含义是连字符-或者点符.。 但是,如果当连字符不是第一个字符时,比如[a-z],这就表示是从字母a到字符z。

  2. []中的^ ^在之前介绍中,是表示一行开头,但是在[]中,有着不同的含义。 [ab] 表示a或者b [^ab] 啥都行,只要不是a或b(anythings except a and b),相当于取反

1.2.4. []和()

除了使用[]表示或逻辑,()也是可以的。用法是(a|b)表示a或者b

比如下面的例子,匹配所有email

[email protected]  
[email protected] 
[email protected]
复制代码

思路:

首先要想我到底相匹配什么,这里我想匹配的是

  1. 任何一个以words开头的,一个或更多 \w+
  2. 紧接着是一个@符号 \w+@
  3. 接着有一个或者更多的words \w+@\w+
  4. 接着一个.标点 \w+@\w+\.
  5. 接着一个com netedu \w+@\w+\.(com|net|edu)

还是提醒注意第四步的\.转义符号

好了,这样几可以匹配以上的所有邮箱了。但是还有一个问题,因为邮箱用户名是可以有.的,比如[email protected]

其实仍然很简单,修复如下: [\w.]+@\w+\.(com|net|edu)

1.2.5. 总结

  1. []的作用,用英文表达就是"alternation",表达一个或的逻辑;
  2. /[-.(]/ 在符号中的连字符-放在第一位表示连字符本身,如果放在中间,表示"从..到..",比如[a-z]表示a-z
  3. [.)] 括号中的特殊符号不需要转义,就表示其本身
  4. [^ab] 括号中的^表示非,anythings except a and b
  5. (a|b)也可表示选择,但是它有更强大的功能....

所以,()的强大功能是什么呢? 分组捕获,这对序列的替换、交换是很有帮助的。 后面一节进行学习记录

1.3. 分组捕获(capturing groups)

什么是分组捕获,现在回到之前电话号码的例子

212-555-1234
915-412-1333

//我想要保留区号,把后面的电话号码变为通用性的

猜你喜欢

转载自blog.csdn.net/JebySin/article/details/81335702