正则表达式
标签(空格分隔): linux
和妹子相处的要义是:若妹子涉世未深,就带她看尽人间繁华;若她心已沧桑,就带她坐旋转木马。 引自《来自未知的撩妹技能》
前述
正则表达式在匹配和一些脚本中使用。个人认为在一些情况下是很有用的。下面是根据jack的述说和网上的一份正则表达式30分钟入门的教程总结的一份表述,留待以后查看。
还是那句话,学习新知识还是得使用20/80原则,正则表达式很复杂,复杂到可以写成一本100~200页的书,所以,我们不可能一次性掌握,所以选择学习其中的20%常用的(可以把正则使用起来的)技能,来满足我后面80%的工作。其他情况在你掌握那20%之后可以随时添加。
下面从一些原理上或者说一些记忆方法上来说正则表达式。
正则表达式可以按照下面的两个方向去看
1 怎么表示一个字符 2 怎么控制一个字符的个数
这里这个方向我感觉很好,我们在使用正则去匹配的时候面对的不就是字符么,而匹配的对象有的属性就是:单个字符是什么,字符的个数这两个基本的属性。
1.怎么表示一个字符
- 普通字符 也就是那些非特殊字符
比如abc 那么它就会匹配”abc”
(1)正则匹配工具会提供一个忽略大小写的选项,这有可能匹配到 “Abc” “ABC” “aBc”等一些结果。
(2)但是有个问题是当你去匹配”abc”的时候,会得到”abc” “leoabc” “abcjack” “12abc3”等一些结果。这个时候我们就需要一些规则来帮助我们让匹配程序知道我需要精确匹配”abc”这三个字符。使用正则的特殊字符”\b”,匹配表达式:”\babc\b”。
“\b”是一个特殊代码,也有人叫它为元字符,他的作用是匹配一个位置,代表单词的开头或结尾,也是单词的分界处。
- 特殊字母(元字符)
但是这些字母也只是表示一个字母 一定注意特殊字符也只能代表一种字符
“.” 点代表除换行符以外的任意一个字符
“*” 代表前面的内容可以连续重复使用任意次以使整个表达式得到匹配。
因此”.*”就代表任意数量不包含换行符的字符。
结合上面的 \babc\b.*\bJack\b 的意思就是:先是一个单词hi,然后任意个任意字符(但不能换行),最后是Jack的字符。
下面,我们看看具体有哪些特殊字符(元字符)
代码 | 说明 |
---|---|
. | 匹配除换行符以外的任意字符 |
\w | 匹配字母或者数字或者下划线或者汉字 |
\s | 匹配任意空白符 |
\d | 匹配数字 |
\b | 匹配单词的开头或结尾(占一个位置) |
^ | 匹配单词的开始 |
$ | 匹配单词的结尾 |
2.怎么控制字符的个数
“^\d{5,12}$” 现学现用,这个可以用来匹配5到12位的qq号码。这里的”{5,12}”表示的就是前面字符的重复次数不得少于5次,不得多于12次。”^”和”$”匹配开始和结尾。
前面也提到一个 “*” 字符,也是控制未知字符个数的一种方式。
这样你就明白了一种控制字符个数的方式了。”{}”也是最为简便明了的方式了。
下面是各种控制字符的方式:
代码/语法 | 说明 |
---|---|
* | 重复零次或更多次 |
+ | 重复一次或者更多次 |
? | 重复零次或者一次 |
{n} | 重复n次 |
{n,} | 重复n次或者更多次 |
{n,m} | 重复n到m次 |
“?” = {0,1},比如,Jacki?Linux表示匹配JackLinux或者JackiLinux
“*” = {0,}.
“+” = {1,},比如, \w+ 表示匹配一次词,一个词表示由一个或一个以上的字符组成的字符串。
这三个字符的特殊用法还有:
- \?\*\+ 表示转义之后的 “?*+”
重复的例子:
Linux\d+ Linux后面跟1个或者更多的数字。
3.转义字符
所谓转义字符,就是当我们需要匹配的字符是前面提到的特殊字符时候,就需要使用转义来让计算机认为这是一个一般的字符,没有什么特殊含义。
很简单,跟其他语言里面的一样:使用 “\” 来转义。
比如.就表示匹配点 这时候点不在表示任意字符
到这里,你已经掌握了基本的: 怎么表示一个字符 怎么控制一个字符的个数。
自此“海阔凭鱼跃 山高任鸟飞”
你已经可以写一些不是很复杂的正则表达式来匹配一些场景了。
比如:匹配座机号码以0开头,后面接2-3个数字,再接“-”然后后面接7位数字,如下所示:
^0\d{2,3}-\d{7}$
4.字符集(字符类)
这个其实前面说过一点,也很好理解。原作者把这个叫做字符类,我就叫做字符集了。
数字[0-9]有特殊字符 \d 来表示了,但是有些我们自己定义的字符集合呢。
比如说,我想要匹配p,a,d,i四个字符中的一个呢。这时候就使用字符集。
like this: [ipad]就可以了。
\w = [0-9a-zA-Z_]
\d = [0-9]
盗用作者的一个例子来说下,这个表达式比较复杂:
下面是一个更复杂的表达式:(?0\d{2}[) -]?\d{8}。
这个表达式可以匹配几种格式的电话号码,像(010)88886666,或022-22334455,或02912345678等。我们对它进行一些分析吧:首先是一个转义字符(,它能出现0次或1次(?),然后是一个0,后面跟着2个数字(\d{2}),然后是)或-或空格中的一个,它出现1次或不出现(?),最后是8个数字(\d{8})。这里的“()”是特殊字符。
5.分枝条件
相当于C语言的与条件表达式,满足其中任意一个就匹配。
blu(e|r)ed这个代表blueed或者blured也就是这样的话只是e或者r不是整个单词。
或者是作者的例子:
匹配三位区号的电话号码与四位区号的电话号码 010-12345678或者0376-2233445
表达式: 0\d{2}-\d{8}|0\d{3}-\d{7}
6.分组
前面有重复单个字符的方式了,那么有没有想过重复多个字符的方式呢。
那么就是分组。 “()”是特殊字符,在他里面的就是一个整体。
好吧,作者的例子很强大,贴上吧。
匹配ip地址的例子,因为ip地址有大小限制:
IP地址中每个数字都不能大于255. 经常有人问我,01.02.03.04 这样前面带有0的数字,是不是正确的IP地址呢? 答案是: 是的,IP 地址里的数字可以包含有前导 0 (leading zeroes).
所以需要使用分组来选择。
((2[0-4]\d|25[0-5]|[01]?\d\d?).){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)
理解的关键是:2[0-4]\d|25[0-5]|[01]?\d\d?
7.最后最后–反义匹配
这个看表就知道了。
代码/语法 | 说明 |
---|---|
\W | 匹配任意不是字母,数字,下划线,汉字的字符 |
\S | 匹配任意不是空白符的字符 |
\D | 匹配任意非数字的字符 |
\B | 匹配不是单词开头和结尾的位置 |
[^x] | 匹配除了x以外的任意字符 |
[^aeIoU] | 匹配除了aeIoU的以外的任意字符 |
\S+匹配不包含空白符的字符串。
ok,到此为止!!!
还有好多的东西,但是我觉得这些已经够我的基本使用了,30分钟了解正则表达式,我只是需要看懂和写一些基本的正则表达式。
谢谢30分钟教程的作者,在这里加上你的链接以表示我的谢意。
正则表达式30分钟入门教程