正则表达式
正则表达式的起源
正则表达式源于人类神经系统工作原理研究,一种用数学方式描述神经网络的新方法
正则表达式的基本概念
正则表达式是一种可以用于文字模式匹配和替换的工具,由一系列普通和特殊字符组成的能明确描述文本字符串的文字匹配模式.
通过正则表达式构建能明确描述文本字符串的匹配模式.
正则表达式的特点
- 灵活性,逻辑性和功能性非常强;
- 可以迅速地极简的方式达到字符串的复杂控制.
- 比较晦涩难懂
正则表达式中常用符号的定义
普通字符
普通字符包没有显式指定为元字符有可打印和不可打印字符,包括所有大/小写字母,所有数字,所有标点符号和一些其他符号.
非打印字符
非打印字符也可以是正则表达式的组成部分. \
| 字符 | 描述 |
|---|---|
| \cx | 匹配由x指明的控制字符,例如,\cM匹配一个Control-M或回车符号.x的值必须为A-Z或a~z之一,否则,将c视为一个原义的"c"字符 |
| \f | 匹配一个换页符,等价于\x0c和\cL |
| \n | 换行符,\x0d,\cJ |
| \r | 回车符,\x0d,\cM |
| \s | 匹配任何空白字符,包括空格,制表符,换页符... 等[\f\n\r\t\v] |
| \S | 匹配任何非空白字符,等价于[^\f\n\r\t\v] |
| \t | 匹配一个制表符,等价于x09和\cl |
| \v | 匹配一个垂直制表符,等价于\x0b和\cK |
特殊字符
所谓特殊字符,就是一些有特殊含义的字符,如上面说的"*.txt"中的*,简单地说就是表示任何字符串的意思.如果要查找文件名有*的文件,则需要对*进行转义,即在前加一个. ls *.txt.
许多元字符要求在试图匹配它们时特别对待.若要匹配这些特殊字符,必须首先使字"转义",即将反斜模杠放在它们前面,
| 特别字符 | 描述 |
|---|---|
| $ | 匹配输入字符串的结尾位置 |
| () | 标记一个子表达式的开始和结束位置 |
| * | 匹配前面的子表达式零次或多次 |
| + | 匹配前面的子表达式一次或多次 |
| . | 匹配除换行符\n 之外的任何单字符. |
| [ | 标记一个中括号表达式的开始 |
| ? | 匹配前面的子表大家式零次或一次,或指明一个非贪婪限定符 |
| \ | 将下一个字符标记为或特殊字符,或原意字符,或后引用或八进制专义字符 |
| ^ | 匹配输入字会串的开始位置,除非在方括号表达式中使用,此时它表示不接受该字符集合 |
| { | 标记限定符表达式的开始. |
| | | 指明两项之间的一个选择. |
限定符
限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配.
| 特别字符 | 描述 |
|---|---|
| * | 匹配前面的子表达零次或多次 ,zo*能匹配z以及zoo *等价于{0,} |
| + | 匹配前面的子表达式一次或多次 "zo+"能匹配zo ,zoo 但不能匹配z |
| ? | 匹配前面的子表达式零次或多次. "do(es)?",可以匹配do does ?等价于{1,} |
| {n} | N是一个非负数,匹配确定的n次 o{2}不能匹配Bob中的o但是能匹配food的两个o |
| {n,} | n是一个非负整数,至少匹配n次,例如,"o{2,}" 不能匹配Bob,但能匹配foooooood中所有的o {1,0}等价于o+,o{0,}等价于o* |
| [ | 标记一个中括号表达式的开始. |
| {n,m} | m,n均为非负整数其中n<=m,最少匹配n次且最多匹配m次,o{1,3} fooooooood中前三个o o{0,1}等价于o? |
正则表达式常用匹配规则.
基本模式匹配
一切从最基本的开始.模式是正规表达式最基本的元素,它们是一组描述字符串特征的字符,模式可以很简单,由普通的字符串组成,也可以非常复杂,往往用特殊的字符表示一个范围内的字符,重复出现,或表示上下文.
^once
这个模式包含一个特殊字符,表示该模式只匹配那些以once开头的字符串,
例如,该模式与字符串 once upon a time匹配,与there once was a man from NewYork 不匹配,正如^符号表示开头一样,$等号用来匹配那些以给定模式结尾的字符串.
bucket$
这个模式与"Who kept all of this cash in a bucket"匹配,与buckets不匹配.字符^与$同时使用时,表示精确匹配
^bucket$
只能匹配字符bucket,如果一个模式不包括^和$,那么它与任何含该模式的字符串匹配.
once
与字符串
There once was a man from NewYork
Who kept all of this cash in a bucket
是匹配的
字符簇
在INTERNET程序中,正则表达式通常用来验让用户的输入.当用户提交一个FORM以后,要判断输入的电话号码,地址,EMAL地址,信用卡号码是否有效,有普通的基于字面的字符是不够的. 所以要用一种更自由的描述需要的模式的办法, 它就是字符簇.要建立一个表示所有元音字符的字符簇,就把的有的元音字符放在一个方括号里:
AaEeIiOoUu
这个模式与任何元音字符匹配,但只能表示一个字符,用连字号可以表示一个字符的范围.
bash
[a-z] # 匹配所有的小写字母
[A-Z] # 匹配有所的大写字线
[a-zA-Z] # 匹配所有的字母
[0-9] # 匹配所有的数字
[0-9\.\-] # 匹配所有的数字,句号与减号
[\f\r\t\n] # 匹配所有的空白字符
同样的,这些也只表示一个字符,这是一个非常重要的,如果要匹配一个由小写字母与数字组成的字符串 如 z2要用下面的模式
^[a-z][0-9]$
第一字符不是数字的
[^0-9][0-9]
排除字符
bash
[^a-z] # 除了小写字母
[^\\\/\^] # 除了\ / ^的字符
[^\"\'] # 除了" ' 的字符
确定重复出现
到现在为止,只是匹配一个字符,更多的时候要匹配一个单词,或一组数字.跟在字符或字符簇后的花括号{}用业确定前面的内容的重复出现的次数
| 字符簇 | 描述 |
|---|---|
| ^[a-zA-Z_]$ | 所有字母和下划线 |
| ^[[:alpha:]]{3}$ | 所有的3个字母的单词 |
| ^a$ | 字母a |
| ^a{4}$ | aaaa |
| ^a{2,4}$ | aa,aaa,aaaa |
| ^a{1,3}$ | a,aa,aaa |
| ^a{2,}$ | 包含多余两个a的字符串 |
| ^a{2,} | 如 aarkdvark 和aaab但apple不行 |
| a{2,} | 如 baad aaa但Nantucket不行 |
| \t{2} | 两个制表符 |
| .{2} | 所有的两个字符 |
花括号里前面的数字表示出现的次数,后面表示不超过该数字
c
^[a-zA-z0-9_]{1,}$ //所有字母与数字或下划给
^[0-9]{1,}$ //所有的正数
^\-{0,1}[0-9]{1,}$ //所有的整数
^[-]?[0-9]+\.?[0-9]+$//所有的浮点数
最后的?相当于{0,1}
^\-?[0-9]{0,}\.?[0-9]{0,}$
以上写法代替版
c
^[a-zA-Z0-9_]+$
^[0-9]+$
^\-?[0-9]+$
正则表达式应用部分示例
简单表达式
正则表达式的最简单形式是在搜索字符串中匹配基本身的单个普通字符.
c
/a/
/7/
/M/
字符匹配
句点(.)匹配字符串中的各种打印或非打印字符,只有一个字符例外.这个例外就是换行符(\n).下面的正则表大家式匹配aac,abc,acc adc等,
/a.c/
若要匹配包含文件名的字符串,而句点(.)是输入字符串的组成部分,请在正则表达式中的句点前加反斜械()
/filename\.ext
中括号表达式
若要创建匹配字符组的一个列表,请在方括号([和])内放置一个或更多个单个字符.当字符括在中括号内时,该列表称为"中括号表达式".与在任何别的位置一样,普通字符在中括号内表示其本身,即它在输入文本中匹配一次其本身,大多数特殊字符大中括号表达内出现时失去它们的意义,不过也有一些例外,
如果]字符不是第一项,它结束一个列表;若要匹配表中的]字符,请将它放大第一位,紧跟在开始[后面.
字符继续作为传义字符,若要匹配\字符,请使用\\
括在中括号表达式中的字符只匹配处于正则表达中该位置的单个字符,以下正则表达式匹配Chapter1,Chapter2,Chapter3,Chapter4和Chapter5:
/Chapter [12345]
请注意单词 Chapter和后面的空格的位置相对于中括号内的字符是固定的,中括号表达式指定的只是匹配紧跟在单词Chapter和空格后面的单个字符位置的字符集.
若要使用范围代替字符本身表示匹配
来表示匹配字符组,请使用连字符-将范围中的开始字符和结束字符分开,单个字符的字符值确定范围内的相对顺序.下面的正则表达式包含范围表达式,该范围表达式等效于上面显示的中括号中的列表.
/Chapter [1-5]/
当以这种方式指定范围时,开始值和结束值两者都包括在范围内,注意,要按Unicode排序顺序,开始值必段在结束值的前面.
若要在中括号中包括连字符,请采用下列方法之一.
(1) 用反斜杠将它转义
[\-]
(2) 将连字符放在中括号列表的开始或结尾.
[-a-z]
[a-z-]
(3) 创建一个范围,在该范围中,开始字符值小于连字符,而结束字符值等于或大于连字符,
[!--]
[!-~]
若要醒找不在列晴勤勤或范围内的所有字符,请将插符号(^)放在列表的开头.如果插入字符出现在列表中的其他任何位置,则它匹配其本身.
/Chapter [^1-5]
替换和分组
替换使用|字符来允许在两个字符或式个替换选项之间进行选择.例如,可以扩展章节标题正则表达式,以返回比章标题范围更广的匹配项.
-
匹配的是Charpter,或Section 22数字
/^Chapter|Section[1-9][0-9]{0,1}$ -
匹配 Chapter22 字母加数字或Section22 字母加数字
/^(Chapter|Section [1-9][0-9]{0,1}$) -
加预测先行
/^(?:Chapter|Section)[1-9][0-9]{0,1}$
正向预测先行使用?= 它匹配处于括号中匹配正则表达式模式的超始点的搜索字符串,
/windows(?=95|98|NT)/
如果匹配 windows98 将在windows之后面不是在98之后继续搜索
反向预测使用?! 它匹配处于与正则表达式模式不匹配的字符串的超始点的搜索字符串.
其他示例
| 正则表达式 | 描述 |
|---|---|
/\b([a-z]+) +\1\b/gi |
一个单词连续出现的位置 |
/(\w+):\/\/([^/:]+)(:\d*)?([^# ]*)/ |
将一个URL解析为协议,域,端口及相对路径 |
| `/^(?:Chapter | Section)[1-9][0-9]{0,1}$/` |
/[-a-z]/ |
a至z共26个字母再加一个-号 |
/ter\b/ |
可匹配chapter,而不能匹配terminal |
/\Bapt/ |
可匹配chpter,不能aptitude |
| `/Windows(?=95 | 98 |
^\s*$/ |
匹配空行 |
/\d{2}-\d{5}/ |
验让由两位数字,一个连字符再加5位数组成的ID号 |