1.正则表达式是什么?
指我们用一段根据某种句法规则写出的字符串来对我们要求的目的字符串进行描述。
2.为什么要用正则表达式?
可以这么说,正则表达式能做的,都能够通过正常的编程来实现。那么我们为什么还要学习正则呢?原因很简单:
1)正则表达式能够很大幅度的简化代码,实现起来也更为顺手;
2)用正则表达式去处理字符串,代码更容易理解;
3)通常来说,正则表达式的速度远比自己写逻辑要高很多;
3.元字符详细介绍
元字符 | 描述 | |||
字符组(单个字符条件) | 边界描述 (不消耗待批配字符串中的字符) | \A(字母开端) | 仅匹配字符串开头。 | |
\Z(字母结尾) | 仅匹配字符串末尾。 | |||
^ | 匹配输入字符串的开始位置(单行)。如果设置了RegExp对象的Multiline属性(即设置了多行模式),匹配每一行的开头。 | |||
$ | 匹配输入字符串的结束位置(单行)。如果设置了RegExp对象的Multiline属性(即设置了多行模式),匹配每一行的末尾。 | |||
\b | 匹配一个单词边界,也就是指单词和空格间的位置。 例如,“er\b”可以匹配“never ”中的“er”,但不能匹配“verb”中的“er”。 | |||
\B | 匹配非单词边界。“er\B”能匹配“verb”中的“er”,但不能匹配“never”中的“er”。 | |||
字符集合 | [xyz]
| (正值)字符集合,匹配所包含的任意一个字符。这里的x、y、z可以是如a-z的一个序列也可以是单个字符。 例如,“[abc]”可以匹配“plain”中的“a”。 | ||
[^xyz] | 负值字符集合,匹配未包含的任意字符。 例如,“[^abc]”可以匹配“plain”中的“plin”。 | |||
[a-z] | 字符范围,匹配指定范围内的任意字符。 例如,“[a-z]”可以匹配“a”到“z”范围内的任意小写字母字符。 | |||
[^a-z] | 负值字符范围,匹配任何不在指定范围内的任意字符。 例如,“[^a-z]”可以匹配任何不在“a”到“z”范围内的任意字符。 | |||
| \ | 将下一个字符标记为一个特殊字符、或一个原义字符、或一个向后引用、或一个八进制转义符。 例如,“\n”匹配一个换行符。“\\n”匹配字符"n"。序列“\\”匹配“\”而“\(”则匹配“(”。 | ||
| \cx | 匹配由x指明的控制字符。例如,\cM匹配一个Control-M或回车符。x的值必须为A-Z或a-z之一。否则,将c视为一个原义的“c”字符。 | ||
特殊功能:关于空白的控制 | \a | 报警字符(打印它的效果是电脑嘀一声) | ||
\f | 匹配一个换页符。等价于\x0c和\cL。 | |||
\n(ew line) | 匹配一个换行符。等价于\x0a和\cJ。 | |||
\r | 匹配一个回车符。等价于\x0d和\cM。 | |||
\t(able) | 匹配一个制表符。等价于\x09和\cI。 | |||
\v(ertical) | 匹配一个垂直制表符。等价于\x0b和\cK。 | |||
\s(pace) | 匹配任何空白字符,包括空格、制表符、换页符等等。等价于[\f\n\r\t\v]。 | |||
\S(pace) | 匹配任何非空白字符。等价于[^\f\n\r\t\v]。 | |||
单词控制 | \w(ord) | 匹配包括下划线的任何单词字符。等价于“[A-Za-z0-9_]”。 | ||
\W(ord) | 匹配任何非单词字符。等价于“[^A-Za-z0-9_]”。 | |||
| .点 | 匹配除“\n”之外的任何单个字符。要匹配包括“\n”在内的任何字符,请使用像“[\s\S]”的模式。 | ||
数据控制 | \d(ecimal) | 匹配一个数字字符。等价于[0-9]。 | ||
\D(ecimal) | 匹配一个非数字字符。等价于[^0-9]。 | |||
\unnnn | Unicode代码中十六进制代码为nnnn的字符。 例如,\u00A9匹配版权符号©。 | |||
\xnn | ASCII代码中十六进制代码为nn的字符。 例如,“\x41”匹配“A”,而“\x041”则等价于“\x04&1”。 | |||
\0nn | ASCII代码中八进制代码为nn的字符。 | |||
\n | 标识一个八进制转义值或一个向后引用。如果\n之前至少n个获取的子表达式,则n为向后引用。否则,如果n为八进制数字(0-7),则n为一个八进制转义值。 | |||
\nm | 标识一个八进制转义值或一个向后引用。如果\nm之前至少有nm个获得子表达式,则nm为向后引用。如果\nm之前至少有n个获取,则n为一个后跟文字m的向后引用。如果前面的条件都不满足,若n和m均为八进制数字(0-7),则\nm将匹配八进制转义值nm。 | |||
\nml | 如果n为八进制数字(0-7),且m和l均为八进制数字(0-7),则匹配八进制转义值nml。 | |||
字符个数控制 | * | 匹配前面的子表达式零次或多次。例如,zo*能匹配“z”以及“zoo”。*等价于{0,}。 | ||
+ | 匹配前面的子表达式一次或多次。例如,“zo+”能匹配“zo”以及“zoo”,但不能匹配“z”。+等价于{1,}。 | |||
? | 匹配前面的子表达式零次或一次。例如,“do(es)?”可以匹配“do”或“does”。?等价于{0,1}。 | |||
{n} | n是一个非负整数。匹配确定的n次。例如,“o{2}”不能匹配“Bob”中的“o”,但是能匹配“food”中的两个o。 | |||
{n,} | n是一个非负整数。至少匹配n次。 例如,“o{2,}”不能匹配“Bob”中的“o”,但能匹配“foooood”中的所有o。“o{1,}”等价于“o+”。“o{0,}”则等价于“o*”。 | |||
{n,m} | m和n均为非负整数,其中n<=m。最少匹配n次且最多匹配m次。 例如,“o{1,3}”将匹配“fooooood”中的前三个o。“o{0,1}”等价于“o?”。请注意在逗号和两个数之间不能有空格。 | |||
? | 当该字符紧跟在任何一个其他限制符(*,+,?,{n},{n,},{n,m})后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。 例如,对于字符串“ww”,“w?”将匹配单个“w”,而“w??”将不匹配“w”。 注意:对<OPTION value="待处理">待处理</OPTION>,^<.*?>中的非贪婪?会至少将到第一个>之前的位置填满,表示以尽可能少的字符达到>,而不会引申到第二个> | |||
捕获组 | 普通捕获组 | (exp) | 将内部exp作为一个整体,并获取这一匹配(参与匹配并获取编号)。所获取的匹配可以从产生的Matches集合得到,在VBScript中使用SubMatches集合,在JScript中则使用$0…$9属性。要匹配圆括号字符,请使用“ ”或“ ”。 | |
(?:exp) | 将内部exp作为一个整体,但不获取匹配结果,也就是说不进行编号存储供以后使用(参与匹配不获取编号)。这在使用或字符“(|)”来组合一个模式的各个部分是很有用。例如“industr(?:y|ies)”就是一个比“industry|industries”更简略的表达式。 | |||
命名捕获组 | (?P<name>exp) | 除了原有的编号外再指定一个额外的别名。 如”(?P<id>abc)”能匹配”abcabc” | ||
(?P=name) | 引用别名为name的分组匹配到的字符串。 如”(?P<id>\d)abc(?P=id)”匹配”1abc1”。 | |||
\num | 引用编号为num的分组匹配到的字符串。 例如,”(\d)abc\1”匹配”3abc3”。 | |||
| (?(id/name)yes_exp[|no_exp]) | 如果编号为id或别名为name的组匹配到字符,则需要匹配yes_exp,否则匹配no_exp。|no_exp也可省略。 如”(\d)abc(?(1)\d|abc)”能匹配到”2abc3”。 | ||
字符组逻辑 | x|y 隐式表达(x)|(y) | 匹配x或y,将x、y当作一个整体,而在上述其他字符操作中如abc+其中的+只是对单一的c操作,却不是对abc整体。例如,“z|food”能匹配“z”或“food”。“(z|f)ood”则匹配“zood”或“food”。 | ||
条件描述(与上述分组区分不作为分组,仅作为条件表达,不参与匹配故不消耗字符) | (?=exp) | 正向肯定条件预查,在任何匹配exp的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如,“Windows(?=95|98|NT|2000)”能匹配“Windows2000”中的“Windows”,但不能匹配“Windows3.1”中的“Windows”。 | ||
(?!exp) | 正向否定条件预查,在任何不匹配exp的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如“Windows(?!95|98|NT|2000)”能匹配“Windows3.1”中的“Windows”,但不能匹配“Windows2000”中的“Windows”。 | |||
(?<=exp) | 反向肯定条件预查,与正向肯定预查类似,只是方向相反。例如,“(?<=95|98|NT|2000)Windows”能匹配“2000Windows”中的“Windows”,但不能匹配“3.1Windows”中的“Windows”。 | |||
(?<!exp) | 反向否定条件预查,与正向否定预查类似,只是方向相反。 例如“(?<!95|98|NT|2000)Windows”能匹配“3.1Windows”中的“Windows”,但不能匹配“2000Windows”中的“Windows”。 | |||
(?iLmsux) | iLmsux的每个字符代表一个匹配模式,只能在表达式左侧的开头,可选多个,即局部模式定义,区别于在表达式尾部写的全局模式定义。 如”(?i)abc”表示忽略a的大小写,能匹配Abc。 | |||
(?#explanation) | #之后的内容将作为注释被忽略。 如”test(?#commet)123”能匹配abc123。 |
【注释】
不消耗字符:在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而 不是从包含预查的字符之后开始。
描述与匹配:描述是一种形容,是对自己的一种表述;匹配是一种动作,表示这种功能。
数组编号:简单来说,组就是放置在圆括号里内的子模块,组的序号取决于它左侧的括 号数。组0就是整个模块,所以在下面的模式中:
‘There (was a (wee) (cooper)) who (lived in Fyfe)’
包含组有:
0 There was a wee cooper who lived in Fyfe
1 was a wee cooper
2 wee
3 cooper
4 lived in Fyfe
实例
(1)匹配双字节字符(包括汉字在内)
Regex:[^\x00-\xff]
(2)从一个字符串中提取链接地址。比如下面字符串中:
<a href=http://hi.baidu.com/mianshiti/blog/category/微软面试题> 微软面试题 </a> ,
则需要提取的地址为 http://hi.baidu.com/mianshiti/blog/category/微软面试题
Regex:(?<=f=).*(?#can be +|?)?(?=>)