正则表达式
语法:
普通字符:
包括没有显式指定为元字符的所有可打印和不可打印字符。包括所有的大写和小写字母、所有的数字、标点符号和一些其他符号
非打印字符:
\cx 匹配由x指明的控制字符。例如,\cM匹配一个Control-M或者回车符。x的值必须为A-Z或a-z之一,否则将c视为一个原义的“c”的字符
\f 匹配一个换页符。等价于\x0c和 \cL
\n 匹配一个换行符。等价于\x0a和\cJ
\r 匹配一个回车符。等价于\x0d和\cM
\s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于[\f\n\r\t\v]
\S 匹配任何非空白字符。等价于[^\f\n\r\t\v]
\t 匹配一个制表符。等价于\x09和\cl
\v 匹配一个垂直制表符。等价于\x0b和\cK
特殊字符
$ 匹配输入字符串的结尾位置。如果设置了ReExp对象的Mulitiline属性,则$也匹配‘\n’或‘\r’,要匹配$字符本身,需要转义 \$
() 标记一个子表达式的开始和结束为止。子表达式可以获取供以后使用。要匹配这些字符,也需要转义 \( \)
* 匹配前面的子表达式0次或者多次,要匹配该字符需要转义 \*
+ 匹配前面的子表达式一次或多次,要匹配该字符需要转义\+
. 匹配除了换行以外的所有单字符。要匹配“.”,需要转义
[ 标记一个中括号表示表达式的开始,要匹配该字符,请转义
? 匹配前面的字表达式0次或者1次或指明一个非贪婪限定词。要匹配该字符,请使用转义字符转义
\ 转义字符,如果要匹配该字符,可以\\
^ 匹配字符串的开始位置,除非在方括号表达式中使用,此时它表示不接受该字符集合。要匹配该字符本身,需要转义
{ 标记限定字符表达式的开始。要匹配该字符需要转义
| 指明两项之间的一个选择,要匹配该字符需要先转义
限定符
限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。有*或者?或者{n}或{n,}或者{n,m}六种
* 匹配前面的子表达式0次或者多次 例如zo*能匹配z以及zoo,等价于{0,}
+ 匹配前面的子表达式一次或者多次。例如zo+能够匹配zo以及zoo但是不能匹配z,相当于{1,}
? 匹配前面的字表达式0次或者1次,相当于{0,1}
{n} 匹配前面的字表达式n次,等价于*
{n,} n是一个非负整数至少匹配n次
{n,m} n和m均为非负整数,其中n<=m。最少匹配n次且最少匹配m次
例子:
由于张杰编写在大的输入文档中可能会超过9,所以需要一种方式;爱处理两位或是3位章节编号。限定符给您这种能力
匹配任何位数的章节标题 /Chapter [1-9][0-9]*/
注意,限定符出现在范围表达式之后,因此,它应用于整个范围表达式,在本例中,只能制定从0-9的数字
如果是99章 /Chapter [0-9]{1,2}/ 缺点是大于99的章节仍只匹配开头两位数字。另一个缺点是Chapter 0也将匹配。只匹配两位数的更好的表达式如下:
/Chapter [1-9][0-9]?/或/Chapter [1-9][0-9]{0,1}/
*、+和?限定符都是贪婪的,因为它们会尽可能多的匹配文字,只有在他们后面再加上一个?就可以实现非贪婪或者是最小匹配。例如
您需要搜索在HTML文档,以查找括在H1标记内的张杰标题,该文本在您的文档中如下:
<H1>Chapter 1 - Introduction to Regular Expressions <H1>
下面表达式匹配从开始小于符号(<)到关闭H1标记的大于符号(>)之间的所有内容 /<.*>/
如果您只需要匹配开始H1标记,线面的非贪心表达式只匹配<H1> /<.*?>/
通过在*、+或者?限定符之后防止?,该表达式从“贪心”表达式转换为“非贪心”表达式或者是最小匹配
定位符
定位符使您能够将正则表达式固定到行首或者行尾。它们还能使您能够创建这样的正则表达式,这些正则表达式出现在一个单词内、在一个单词的开头或者一个单词的结尾
定位符用来描述字符串或者单词的边界。^和$分别指字符串的开始与结束,\b描述单词的钱或后边界,\B表示词边界
^ 匹配输入字符串开始的位置,如果设置了RegExp对象的Mulitiline属性,^还会与\或是\r之前的位置匹配
$ 匹配输入字符串的结尾的位置,如果设置了RegExp对象的Mulitiline属性,$还会与\n或者\r之前的位置匹配
\b 匹配一个字边界,即字与空格之间的位置
\B 非字边界匹配
注意:不能将限定符与定位点一起使用。由于在紧靠换行或者字边界的前面或后面不能有一个以上位置,因此不允许诸如^*之类的表达式
若要匹配一行文本的开始,则在正则表达式的开始使用^字符。不要将^的这种用法和中括号内的^用法混淆
若要匹配一行文本的结束处的文本,请在正则表达式的结束处使用$字符。
若要在搜索标题时使用定位点,下面的正则表达式匹配一个章节标题,该标题只包含两个尾随数字,并且出现在行首 /^Chapter [1-9][0-9]{0.1}/
真正的章节标题不仅出现行的开始处,而且它还是该行中仅有的文本。它即出现在行首又出现在行尾 /^Chapter [1-9][0-9]{0,1}&/
匹配子边界少有不同,但向正则表达式中添加了很重要的能力。子边界是单词与空格之间的位置 /\bCha/ 匹配Chapter开头三个字符,因为它出现在子边界的后面
\b字符的位置是非常重要的。如果它位于要匹配的字符串的开始,它在单词的开始处查找匹配符,如果它位于要匹配字符的结尾,则它在单词的结尾处匹配字符 /ter\b/ 匹配Chapter中的ter,因为它出现在字边界的前面
下面的表达式匹配Chapter中的apt但是不匹配aptitude中的apt
/\Bapt/ 字符apt出现在单词Chapter中的非字边界处,但出现在单词aptitude的字边界处。对\B来说,非字边界运算符,位置并不重要,因为匹配不关心究竟是单词的开头还是结尾
选择
用圆括号将所有选择项括起来,相邻的选择项之间用|隔开,但是圆括号会有一个副作用,就是相关的匹配会被缓存,此时可用?:放在第一个选项前来消除这种副作用
其中?:是非捕获元之一,还有两个非捕获元是?=和?!,这两个还有更多的意义,前者为正向预查,在任何开始匹配圆括号内的的正则表达式模式的位置来搜索字符串,后者是负向预查,在任何不匹配该正则表达式模式的位置来匹配搜索字符串
反向引用,对一个正则表达式模式或部分模式两边添加圆括号将导致相关匹配存储到一个临时缓存区中,所捕获的每一个子匹配都照在正则表达式模式中从左到右的顺序排序。缓冲区编号从1开始,最多可捕获99个捕获的字表达式。每个缓冲区都可以用‘\n’访问,其中n为一个标识特定缓冲区的一位或者两位十进制数
Is is the cost of of gasoling going up up?
设计一种方法定位该句子,而不必查找没一个单词的重复出现。
/\b([a-z]+) \1\b/gi
[a-z]+ 一个或多个字母
正则表达式第二部分是对以前补货的子匹配项的引用,即单词的第二个匹配项正好由括号表达式匹配。\1指定第一个匹配项。字符边界元字符确保只检测整个单词
正则表达式后面的全局标量g表示将该表达式应用输入字符串中能查到的尽可能多的匹配。表达式的结尾处的不区分大小写标记i指定不区分大小写
分解uri http://www.w3cschool.cc:8080/html/html-tutorial.html
/(\w+):\/\/([^/:]+)(:\d*)?([^# ]*)/
(\w+) :和//前面的任何单词 http
[^/:]+ 非/和:的一个或多个单词 www.w3cshchool.cc
(:\d*)? 冒号后面的0个或多个数字,只能重复一次该表达式 :80
[# ]* 非#和空格的任何字符序列 /html/html-tutorial.html
元字符:
\ 转义字符
^ 匹配输入字符串的开始位置,如果设置了RegExp对象的Mulitiline属性,^也可匹配\n或\r之后的位置 在中括号中^表示非
$ 匹配输入字符串的开始位置,如果设置了RegExp对象的Mulitiline属性,$也可匹配\n或\r之前的位置
* 匹配前面的子表达式0次或多次,相当于{0,}
+ 匹配前面的子表达式1次或多次,相当于{1,}
? 匹配前面的子表达式0次或1次,相当于{0,1} 当该字符仅跟在任何一个其他限制符后面的时候,匹配模式是非贪婪的。非贪婪模式尽可能减少的匹配所搜索的字符串,而默认的贪婪模式将尽可能的多匹配所搜索的字符串。例如对于0000 0+?将匹配单个0,0+将匹配所有0
{n} 匹配前面的子表达式n次,n为非负整数
{n,} 匹配前面的子表达式至少n次,n为非负整数
{n,m} 匹配前面的子表达式n次到m次,n和m都为非负整数,n<=m
. 匹配除\n之外的人以单个字符
(pattern) 匹配pattern并获取这一匹配。所获取的匹配可以从产生的Matches集合得到
(?:pattern) 匹配pattern但不获取匹配结果
(?=pattern) 正向预查,在任何匹配pattern字符串处开始匹配查找字符串。非获取匹配类型。windows(?=95|98|NT|2000)能匹配windows 2000 不能匹配windows 3.1 预查不消耗字符,也就是说在一个匹配发生后,最最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始
(?!pattern) 负向预查,在任何吧不匹配pattern字符串处开始匹配查找字符串。非获取匹配类型。windows(?=95|98|NT|2000)不能匹配windows 2000 能匹配windows 3.1 预查不消耗字符,也就是说在一个匹配发生后,最最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始
x|y 匹配x或者y
[xyz] 字符集合。匹配所包含的任意一个字符
[^xyz] 负值字符集合。匹配所包含字符外的所有字符
[a-z] 字符范围,匹配指定范围内的任意字符
[^a-z]
\b 匹配一个单词边界,单词边界,就是单词和空格之间的位置。前后顺序有影响。\btr 可以匹配tringtbtc中的tr,因为它是在边界后,tc\b可以匹配stringtbtc之中的tc,因为它是在边界前
\B 匹配非单词边界。位置随意,无影响,例如tringtradctr \Btr只能匹配字符串中间的tr,两边的tr都不能匹配,因为它们紧靠单词边界
\cx 匹配x指明的控制字符。例如\cM匹配一个Control-M或者回车符。x的值必须为a-z或A-Z之间,否则c将视为一个原义的c字符
\d 匹配一个数字字符,等价于[0-9]
\D 匹配一个非数字字符,等价于[^0-9]
\f 匹配一个换页符,等价于\x0c和\cL
\n 匹配一个回车符,等价于\x0a和\cJ
\r 匹配一个回车符,等价于\x0d和\cM
\s 匹配任何空白字符,包括空格、制表符、换行符等等,相当于[\f\n\r\t\v]
\S 匹配任何非空白字符,等价于[^\f\n\r\t\v]
\t 匹配一个制表符,等价于\x09和\cl
\w 匹配包括下划线的任何单词字符,等价于[a-zA-Z_]
\W 匹配任何非单词字符,等价于[^a-zA-Z_]
\xn 匹配n,其中n为16进制转义值。十六进制转义值必须为确定的两个数字长。例如\x41匹配A,\x041等价于\x04&1
\num 匹配num,其中num是一个正整数。对所获取的匹配的引用,例如(.)\1匹配两个连续相同的字符
\n 标识一个8进制转义值或一个向后引用。如果\n之前至少n个获取的子表达式,则n为向后引用。否则如果n为八进制数字(0-7),则n为一个八进制转义值
\nm 标识的一个八进制转义值或者一个向后引用。如果\nm之前至少有nm个获得子表达式,则nm为向后引用。如果\nm之前至少有n个获取,则n为一个后跟蚊子m的向后引用。如果前面的条件都不满足,若n和m军委8进制数字(0-7),则匹配8进制转义值nm
\nml 如归n为8进制数字(0-3),且n和l军委八进制数字(0-7),则匹配8进制转义值nml
\un 匹配n,其中n是一个用四个十六进制数字表示的Unicode字符。例如,\u00A9匹配版权符号(?)
优先级:
正则表达式从左到右进行计算,并遵循优先级顺序,这与算术表达式非常类似。
相同优先级的从左到右进行运算,不通优先级的运算先高后低,下表从最高到最低说明了各种正则表达式运算符的优先级顺序:
\ 转义符
(),(?:),(?=),(?!),[] 括号和方括号
*,+,?,{n},{n,},{n,m} 限定符
^,$,\任何元字符,任何字符 定位点和序列(即:位置和顺序)
| 或操作
示例:
简单表达式
/a/
/7/
/M/
可以讲许多单字符组合起来形成大的表达式。例如
/a7M/
请注意,没有串联运算符。必须在一个字符后面键入另一个字符
字符匹配
句点.匹配字符串中的各种字符只有一个字符例外。这个例外就是换行符\n。下面的正则表达式匹配aac、abc、acc、adc等等:
/a.c/
若要匹配包含文件名的字符串,而句点是输入字符串的组成部分,句点需要转义,表示filename.ext
/filename\.ext/
中括号表达式
若呀哦创建匹配字符组的一个列表,请在方括号[]内放置一个或者多个单个字符,当字符括在中括号内的时候该列表称为中括号表达式。与在任何别的位置一样,普通字符在中括号中表示其本身。大多数特殊字符在中括号表达式出现时失去他们的意义,不过也有一些例外,如:
如果]字符不是第一项,它结束一个列表,若要匹配一个列表中的[字符,请把它放在第一位
字符\作为转义字符,如果需要使用\,必须转义\\
括在中括号表达式的字符只匹配处于正则表达式中该位置的单个字符,以下正则表达式匹配Chapter 1、Chapter 2、Chapter 3、Chapter 4、Chapter 5
/Chapter [12345]/
请注意,单词Chapter和后面的空格位置相对于中括号内的字符是固定的。中括号表达式指定的只是匹配紧跟在单词Chapter和空格后面的单个字符位置的字符集。这是第九个字符位置
若要用范围代替字符本身来表示匹配字符组,请使用连字符-将范围中的开始和结束字段分开。单个字符的字符值确定范围内的相对顺序。下面的正则表达式办函范围表达式,该范围表达式等效于上面显示的中括号中的列表
/Chapter [1-5]/
当以这种方式指定范围的时候,开始值和结束值两者都包括在范围内。注意,还有一点很重要,按Unicode排序顺序,开始值必须在结束值前面
若要在中括号表达式中包括连字符,请采用下列方法之一:
用反斜杠将它转义:[\-]
将连字符放在中括号列表的开始或者结尾,下面表达式匹配所有的小写字母和连字符: [-a-z] [a-z-]
创建一个范围,在该范围中,开始值小于连字符,而结束值大于或等于连字符,下面两个都满足要求: [!--] [!-~]
若要查不在列表或范围内的所有字符,请插入符号^到列表的开头
/Chapter [^1-5]/
替换和分组
替换使用|字符来允许在两个或多个替换选项之间进行选择。例如,可以拓展章节标题正则表达式,以返回比章节标题范围更广的匹配项
/^Chapter|Session [1-9][0-9]{0,1}$/ 并非:匹配出现在行首和行尾的Chapter或Session后面接1个或者两个数字,注意优先级(转义>括号>限定>定位>|)
实际:单词Chapter或者Sessioon开头后接一个或两个数字结尾的字符
要使正则表达式更易于控制,可以使用括号来限制替换的范围,即确保它只应用于两个单词Chapter和Session。但是括号也用于创建子表达式,并可能捕获它们供以后使用,通过在上面的正则表达式的适当位置添加括号,就可以使正则表达式实现 匹配出现在行首和行尾的Chapter或Session后面接1个或者两个数字这个效果:
/^(Chapter|Session) [1-9][0-9]{0,1}$/
尽管这些表达式正常工作,但Chapter|Session周围的括号还将捕获两个匹配字中的任一个供以后使用。由于在上面的表达式中只有一组括号,因此,只有一个被捕获的子匹配项
防止匹配被保存:
/^(?:Chapter|Session) [1-9][0-9]{0,1}$/
除了?:元字符外,两个其他非捕获元字符创建被称为“预测先行”匹配的某些内容。正向预测先行使用?=指定,它匹配处于括号中匹配正则表达式模式的起始点的搜索字符串。反向预测先行使用?!指定,它匹配处于与正则表达式模式不匹配的字符串的起点的搜索字符串。
例如,假设您有一个文档,该文档包含指向windows 3.1、windows 95、windows 98和windows NT的引用。再进一步假设,您需要更新该文档,将文档指向windows 3.1、windows98、windows NT的所有引用更改为windows 2000下面的正则表达式(这是一个正向预测先行的示例)匹配windows 95、windows98和windows NT:
/windows(?= 95 |98 |NT)/
找到一处匹配后,紧接着就在匹配的文本(不包含预测先行中的字符)之后搜索下一处匹配。例如,如果上面的表达式匹配windows98,将在windows之后而不是在98之后继续搜索
/windows(?! 95 |98 |NT)/匹配其他windows后面的字段,不能匹配windows 95,windows 98、windows NT
其他示例:
一个单词连续出现的位置: /\b([a-z]+)\1\b/gi g表示贪婪,i表示不区分大小写
将一个url解析为协议、域、端口、相对路径 /(\w+):\/\/[^/:](:\d*)?([^#]*)/
A-z共26个字母再加一个-号 /[-a-Z]/
可以匹配chapter,不能匹配terminal /ter\b/
可匹配chapter,而不能匹配aptitude /\Bapt/
可匹配windows95或windows98或windowsNT,当找到一个匹配后,从windows后面开始进行下一次的检索匹配 /windows(?=95|98|NT)/
匹配空行 /^\s*$/
验证由两位数字、一个连字符再加5位数字组成的ID号 /\d{2}-\d{5}/
匹配HTML标记 /<\s*(\S+)(\s[^>]*)?>[\s\S]*<\s/*\/\1\S*>/
使用说明:
一、正则表达式的创建方式:
1.文本格式,使用方法如下:
/pattern/flags (即:/模式/标记)
RegExp构造函数,使用方法如下:
new RegExp("pattern"[,"flags"]); (即:new RegExp("模式"[,标记]))
参数:
pattern(模式):表示正则表达式的文本
flags(标记): 如果指定此项,flags可以是下面之一:
g:global match(全定匹配)
i:ignore Case(忽略大小写)
gi: both global match and ignore case(匹配所有可能的值,也忽略大小写)
注意:文本格式中的参数不要使用引号标记,构造器的参数则要使用引号标记
/ab+c/i ============= new RegExp("ab+c","i");
描述:
当使用构造器函数创建正则表达式的时候,必须使用正常的字符串避开规则(在字符串前面加上转义字符\)是必须的
re=new RegExp("\\w+"); =========/\w+/
注意:RegExp预置了$属相
$1,....$9
用圆括号括着的匹配字符串,如果有的话。
是RegExp的属性
静态,只读
在JavaScript1.2,ENS 3.0以上版本提供
描述:因为input是静态属性,不是个别正则表达式对象的属性,你可以使用RegExp.input访问该属性
能加上圆括号的字串的数量不受限制,但是正则表达式对象只能保留9条,如果你要访问所有的圆括号内的匹配字符串,你可以使用返回的数组
二:
match()方法可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配。它返回指定的值,而不是字符串的位置。
语法:
stringObject match(searchvalue)
stringObject.match(regexp)参数描述
searchvalue必需。规定要检索的字符串值。
regexp必须。规定匹配模式的RegExp对象。如果该参数不是RegExp对象,则需要首先将它传递给RegExp构造函数,将其转换成RegExp对象
返回值
存放匹配结果的数组。该数组的内容依赖于regexp是否具有全局标志g
说明
match()方法将检索字符串stringObject,以找到一个或多个与regexp匹配的文本。着个方法的行为在很大程度上有赖于regexp是否具有标志g
如果regexp没有标志g,那么match方法就只能在stringObject中执行一次匹配。如果没有找到任何匹配的文本,match()将返回null。否则,它将返回一个数组,其中存放了与它找到的匹配文本有关的信息
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0Transitional//EN"> <HTML> <HEAD> <TITLE> </TITLE> <SCRIPT LANGUAGE="JavaScript1.2"> var str="1 plus equal 3"; var str2="11/23/55"; var result=str.match(new RegExp("\\d+","gi")); for(var i=0;i<result.length;i++){ document.write(result[i]+"<br/>"); } var res=str2.match(new RegExp("(\\d\\d?)/(\\d\\d?)/(\\d\\d)"),"g"); for(var i=0;i<res.length;i++){ document.write(res[i]+"<br/>"); } document.write(parseInt("12",10));<!--parseInt("a",b);取大的int数--> </SCRIPT> </HEAD> <BODY> </BODY> </HTML>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD> <TITLE>RegExp demo</TITLE> <SCRIPT LANGUAGE="JavaScript1.2"> var regexp=new RegExp("(\\w+)\\s(\\w+)"); str="John Smith"; newstr=str.replace(regexp,"$2"); newstr2=str.replace(regexp,"$1"); document.write("原字符串:"+str+"<br/>"); document.write(newstr+"<br/>"); document.write(newstr2+"<br/>"); document.write("$1="+RegExp.$1+" $2="+RegExp.$2); </SCRIPT> </HEAD> <BODY> </BODY> </HTML>
说明:正则表达式通常用于两种任务:1.验证,2.搜索/替换。用于验证时,通常需要在前后分别加上^和$,以匹配整个待验证字符串;搜索 /替换时是否加上此限定则根据搜索的要求而定,此外,也有可能要在前后加上\b而不是^和$。此表所列的常用正则表达式,除个别外均未在前后加上任何限 定,请根据需要,自行处理。
正则表达式(英文:Regular Expression)在计算机科学中,是指一个用来描述或者匹配一系列符合某个句法规则的字符串的单个字符串。
| 说明 | 正则表达式 |
|---|---|
| 网址(URL) | [a-zA-z]+://[^\s]* |
| IP地址(IP Address) | ((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?) |
| 电子邮件(Email) | \w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)* |
| QQ号码 | [1-9]\d{4,} |
| HTML标记(包含内容或自闭合) | <(.*)(.*)>.*<\/\1>|<(.*) \/> |
| 密码(由数字/大写字母/小写字母/标点符号组成,四种都必有,8位以上) | (?=^.{8,}$)(?=.*\d)(?=.*\W+)(?=.*[A-Z])(?=.*[a-z])(?!.*\n).*$ |
| 日期(年-月-日) | (\d{4}|\d{2})-((1[0-2])|(0?[1-9]))-(([12][0-9])|(3[01])|(0?[1-9])) |
| 日期(月/日/年) | ((1[0-2])|(0?[1-9]))/(([12][0-9])|(3[01])|(0?[1-9]))/(\d{4}|\d{2}) |
| 时间(小时:分钟, 24小时制) | ((1|0?)[0-9]|2[0-3]):([0-5][0-9]) |
| 汉字(字符) | [\u4e00-\u9fa5] |
| 中文及全角标点符号(字符) | [\u3000-\u301e\ufe10-\ufe19\ufe30-\ufe44\ufe50-\ufe6b\uff01-\uffee] |
| 中国大陆固定电话号码 | (\d{4}-|\d{3}-)?(\d{8}|\d{7}) |
| 中国大陆手机号码 | 1\d{10} |
| 中国大陆邮政编码 | [1-9]\d{5} |
| 中国大陆身份证号(15位或18位) | \d{15}(\d\d[0-9xX])? |
| 非负整数(正整数或零) | \d+ |
| 正整数 | [0-9]*[1-9][0-9]* |
| 负整数 | -[0-9]*[1-9][0-9]* |
| 整数 | -?\d+ |
| 小数 | (-?\d+)(\.\d+)? |
| 不包含abc的单词 | \b((?!abc)\w)+\b |
以上正则表达式均经过多次测试,并不断增加,因为不同程序或工具的正则表达式略有区别,大家可以根据需要进行简单修改
常用正则表达式
正则表达式用于字符串处理、表单验证等场合,实用高效。现将一些常用的表达式收集于此,以备不时之需。
用户名:/^[a-z0-9_-]{3,16}$/
密码:/^[a-z0-9_-]{6,18}$/
十六进制值:/^#?([a-f0-9]{6}|[a-f0-9]{3})$/
电子邮箱:/^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/
URL:/^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/
IP 地址:/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/
HTML 标签:/^<([a-z]+)([^<]+)*(?:>(.*)<\/\1>|\s+\/>)$/
Unicode编码中的汉字范围:/^[u4e00-u9fa5],{0,}$/
匹配中文字符的正则表达式: [\u4e00-\u9fa5]
评注:匹配中文还真是个头疼的事,有了这个表达式就好办了
匹配双字节字符(包括汉字在内):[^\x00-\xff]
评注:可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1)
匹配空白行的正则表达式:\n\s*\r
评注:可以用来删除空白行
匹配HTML标记的正则表达式:<(\S*?)[^>]*>.*?</\1>|<.*? />
评注:网上流传的版本太糟糕,上面这个也仅仅能匹配部分,对于复杂的嵌套标记依旧无能为力
匹配首尾空白字符的正则表达式:^\s*|\s*$
评注:可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式
匹配Email地址的正则表达式:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*
评注:表单验证时很实用
匹配网址URL的正则表达式:[a-zA-z]+://[^\s]*
评注:网上流传的版本功能很有限,上面这个基本可以满足需求
匹配帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
评注:表单验证时很实用
匹配国内电话号码:\d{3}-\d{8}|\d{4}-\d{7}
评注:匹配形式如 0511-4405222 或 021-87888822
匹配腾讯QQ号:[1-9][0-9]{4,}
评注:腾讯QQ号从10000开始
匹配中国大陆邮政编码:[1-9]\d{5}(?!\d)
评注:中国大陆邮政编码为6位数字
匹配身份证:\d{15}|\d{18}
评注:中国大陆的身份证为15位或18位
匹配ip地址:\d+\.\d+\.\d+\.\d+
评注:提取ip地址时有用
匹配特定数字:
^[1-9]\d*$ //匹配正整数
^-[1-9]\d*$ //匹配负整数
^-?[1-9]\d*$ //匹配整数
^[1-9]\d*|0$ //匹配非负整数(正整数 + 0)
^-[1-9]\d*|0$ //匹配非正整数(负整数 + 0)
^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$ //匹配正浮点数
^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$ //匹配负浮点数
^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$ //匹配浮点数
^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$ //匹配非负浮点数(正浮点数 + 0)
^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$ //匹配非正浮点数(负浮点数 + 0)
评注:处理大量数据时有用,具体应用时注意修正
匹配特定字符串:
^[A-Za-z]+$ //匹配由26个英文字母组成的字符串
^[A-Z]+$ //匹配由26个英文字母的大写组成的字符串
^[a-z]+$ //匹配由26个英文字母的小写组成的字符串
^[A-Za-z0-9]+$ //匹配由数字和26个英文字母组成的字符串
^\w+$ //匹配由数字、26个英文字母或者下划线组成的字符串
表达式全集
正则表达式有多种不同的风格。下表是在PCRE中元字符及其在正则表达式上下文中的行为的一个完整列表:
| 字符 | 描述 |
|---|---|
| \ | 将下一个字符标记为一个特殊字符、或一个原义字符、或一个向后引用、或一个八进制转义符。例如,“n”匹配字符“n”。“\n”匹配一个换行符。序列“\\”匹配“\”而“\(”则匹配“(”。 |
| ^ | 匹配输入字符串的开始位置。如果设置了RegExp对象的Multiline属性,^也匹配“\n”或“\r”之后的位置。 |
| $ | 匹配输入字符串的结束位置。如果设置了RegExp对象的Multiline属性,$也匹配“\n”或“\r”之前的位置。 |
| * | 匹配前面的子表达式零次或多次。例如,zo*能匹配“z”以及“zoo”。*等价于{0,}。 |
| + | 匹配前面的子表达式一次或多次。例如,“zo+”能匹配“zo”以及“zoo”,但不能匹配“z”。+等价于{1,}。 |
| ? | 匹配前面的子表达式零次或一次。例如,“do(es)?”可以匹配“do”或“does”中的“do”。?等价于{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})后面时,匹配模式是非贪婪的。非贪婪模式尽 可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串“oooo”,“o+?”将匹配单个“o”,而“o+” 将匹配所有“o”。 |
| . | 匹配除“\n”之外的任何单个字符。要匹配包括“\n”在内的任何字符,请使用像“[.\n]”的模式。 |
| (pattern) | 匹配pattern并获取这一匹配。所获取的匹配可以从产生的Matches集合得到,在VBScript中使用SubMatches集合,在JScript中则使用$0…$9属性。要匹配圆括号字符,请使用“\(”或“\)”。 |
| (?:pattern) | 匹配pattern但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用或字符“(|)”来组合一个模式的各个部分是很有用。例如“industr(?:y|ies)”就是一个比“industry|industries”更简略的表达式。 |
| (?=pattern) | 正向预查,在任何匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后 使用。例如,“Windows(?=95|98|NT|2000)”能匹配“Windows2000”中的“Windows”,但不能匹配 “Windows3.1”中的“Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从 包含预查的字符之后开始。 |
| (?!pattern) | 负向预查,在任何不匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以 后使用。例如“Windows(?!95|98|NT|2000)”能匹配“Windows3.1”中的“Windows”,但不能匹配 “Windows2000”中的“Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是 从包含预查的字符之后开始 |
| x|y | 匹配x或y。例如,“z|food”能匹配“z”或“food”。“(z|f)ood”则匹配“zood”或“food”。 |
| [xyz] | 字符集合。匹配所包含的任意一个字符。例如,“[abc]”可以匹配“plain”中的“a”。 |
| [^xyz] | 负值字符集合。匹配未包含的任意字符。例如,“[^abc]”可以匹配“plain”中的“p”。 |
| [a-z] | 字符范围。匹配指定范围内的任意字符。例如,“[a-z]”可以匹配“a”到“z”范围内的任意小写字母字符。 |
| [^a-z] | 负值字符范围。匹配任何不在指定范围内的任意字符。例如,“[^a-z]”可以匹配任何不在“a”到“z”范围内的任意字符。 |
| \b | 匹配一个单词边界,也就是指单词和空格间的位置。例如,“er\b”可以匹配“never”中的“er”,但不能匹配“verb”中的“er”。 |
| \B | 匹配非单词边界。“er\B”能匹配“verb”中的“er”,但不能匹配“never”中的“er”。 |
| \cx | 匹配由x指明的控制字符。例如,\cM匹配一个Control-M或回车符。x的值必须为A-Z或a-z之一。否则,将c视为一个原义的“c”字符。 |
| \d | 匹配一个数字字符。等价于[0-9]。 |
| \D | 匹配一个非数字字符。等价于[^0-9]。 |
| \f | 匹配一个换页符。等价于\x0c和\cL。 |
| \n | 匹配一个换行符。等价于\x0a和\cJ。 |
| \r | 匹配一个回车符。等价于\x0d和\cM。 |
| \s | 匹配任何空白字符,包括空格、制表符、换页符等等。等价于[\f\n\r\t\v]。 |
| \S | 匹配任何非空白字符。等价于[^\f\n\r\t\v]。 |
| \t | 匹配一个制表符。等价于\x09和\cI。 |
| \v | 匹配一个垂直制表符。等价于\x0b和\cK。 |
| \w | 匹配包括下划线的任何单词字符。等价于“[A-Za-z0-9_]”。 |
| \W | 匹配任何非单词字符。等价于“[^A-Za-z0-9_]”。 |
| \xn | 匹配n,其中n为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如,“\x41”匹配“A”。“\x041”则等价于“\x04&1”。正则表达式中可以使用ASCII编码。. |
| \num | 匹配num,其中num是一个正整数。对所获取的匹配的引用。例如,“(.)\1”匹配两个连续的相同字符。 |
| \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-3),且m和l均为八进制数字(0-7),则匹配八进制转义值nml。 |
| \un | 匹配n,其中n是一个用四个十六进制数字表示的Unicode字符。例如,\u00A9匹配版权符号(?)。 |
以下是以PHP的语法所写的示例
验证字符串是否只含数字与英文,字符串长度并在4~16个字符之间
<?php
$str = 'a1234';
if (preg_match("^[a-zA-Z0-9]{4,16}$", $str)) {
echo "验证成功";
} else {
echo "验证失敗";
}
?>
简易的台湾身份证字号验证
<?php
$str = 'a1234';
if (preg_match("/^\w[12]\d{8}$/", $str)) {
echo "验证成功";
} else {
echo "验证失敗";
}
?>
以下示例是用 Perl 语言写的,与上面的示例功能相同
print $str = "a1234" =~ m:^[a-zA-Z0-9]{4,16}$: ? "COMFIRM" : "FAILED";
print $str = "a1234" =~ m"^\w[12]\d{8}$" ? "COMFIRM" : "INVAILD";
如何写出高效率的正则表达式
如果纯粹是为了挑战自己的正则水平,用来实现一些特效(例如使用正则表达式计算质数、解线性方程),效率不是问题;如果所写的正则表达式只 是为了满足一两次、几十次的运行,优化与否区别也不太大。但是,如果所写的正则表达式会百万次、千万次地运行,效率就是很大的问题了。我这里总结了几条提 升正则表达式运行效率的经验(工作中学到的,看书学来的,自己的体会),贴在这里。如果您有其它的经验而这里没有提及,欢迎赐教。
为行文方便,先定义两个概念。
误匹配:指正则表达式所匹配的内容范围超出了所需要范围,有些文本明明不符合要求,但是被所写的正则式 “击中了”。例如,如果使用\d{11}来匹配11位的手机号,\d{11}不单能匹配正确的手机号,它还会匹配98765432100这样的明显不是手 机号的字符串。我们把这样的匹配称之为误匹配。
漏匹配:指正则表达式所匹配的内容所规定的范围太狭窄,有些文本确实是所需要的,但是所写的正则没有将这种情况囊括在内。例如,使用\d{18}来匹配18位的身份证号码,就会漏掉结尾是字母X的情况。
写出一条正则表达式,既可能只出现误匹配(条件写得极宽松,其范围大于目标文本),也可能只出现漏匹配(只描述了目标文本中多种情况种的一种),还可能既有误匹配又有漏匹配。例如,使用\w+\.com来匹配.com结尾的域名,既会误匹配abc_.com这样的字串(合法的域名中不含下划线,\w包含了下划线这种情况),又会漏掉ab-c.com这样的域名(合法域名中可以含中划线,但是\w不匹配中划线)。
精准的正则表达式意味着既无误匹配且无漏匹配。当然,现实中存在这样的情况:只能看到有限数量的文本,根据这些文本写规则,但是这些规则将 会用到海量的文本中。这种情况下,尽可能地(如果不是完全地)消除误匹配以及漏匹配,并提升运行效率,就是我们的目标。本文所提出的经验,主要是针对这种 情况。
掌握语法细节。正则表达式在各种语言中,其语法大致相同,细节各有千秋。明确所使用语言的正则的语法的 细节,是写出正确、高效正则表达式的基础。例如,perl中与\w等效的匹配范围是[a-zA-Z0-9_];perl正则式不支持肯定逆序环视中使用可 变的重复(variable repetition inside lookbehind,例如(?<=.*)abc),但是.Net语法是支持这一特性的;又如,JavaScript连逆序环视 (Lookbehind,如(?<=ab)c)都不支持,而perl和python是支持的。《精通正则表达式》第3章《正则表达式的特性和流派概 览》明确地列出了各大派系正则的异同,这篇文章也简要地列出了几种常用语言、工具中正则的比较。对于具体使用者而言,至少应该详细了解正在使用的那种工作 语言里正则的语法细节。
先粗后精,先加后减。使用正则表达式语法对于目标文本进行描述和界 定,可以像画素描一样,先大致勾勒出框架,再逐步在局步实现细节。仍举刚才的手机号的例子,先界定\d{11},总不会错;再细化为1[358] \d{9},就向前迈了一大步(至于第二位是不是3、5、8,这里无意深究,只举这样一个例子,说明逐步细化的过程)。这样做的目的是先消除漏匹配(刚开 始先尽可能多地匹配,做加法),然后再一点一点地消除误匹配(做减法)。这样有先有后,在考虑时才不易出错,从而向“不误不漏”这个目标迈进。
留有余地。所能看到的文本sample是有限的,而待匹配检验的文本是海量的,暂时不可见的。对于这样 的情况,在写正则表达式时要跳出所能见到的文本的圈子,开拓思路,作出“战略性前瞻”。例如,经常收到这样的垃圾短信:“发*票”、“发#漂”。如果要写 规则屏蔽这样烦人的垃圾短信,不但要能写出可以匹配当前文本的正则表达式 发[*#](?:票|漂),还要能够想到 发.(?:票|漂|飘)之类可能出现的“变种”。这在具体的领域或许会有针对性的规则,不多言。这样做的目的是消除漏匹配,延长正则表达式的生命周期。
明确。具体说来,就是谨慎用点号这样的元字符,尽可能不 用星号和加号这样的任意量词。只要能确定范围的,例如\w,就不要用点号;只要能够预测重复次数的,就不要用任意量词。例如,写析取twitter消息的 脚本,假设一条消息的xml正文部分结构是<span class=”msg”>…</span>且正文中无尖括号,那么<span class=”msg”>[^<]{1,480}</span>这种写法的思路要好 于<span class=”msg”>.*</span>,原因有二:一是使用[^<],它保证了文本的范围不会超出下一个小于号所在的位 置;二是明确长度范围,{1,480},其依据是一条twitter消息大致能的字符长度范围。当然,480这个长度是否正确还可推敲,但是这种思路是值 得借鉴的。说得狠一点,“滥用点号、星号和加号是不环保、不负责任的做法”。
不要让稻草压死骆驼。每使用一个普通括号()而不是非捕获型括号(?:…),就会保留一部分内存等着你再次访问。这样的正则表达式、无限次地运行次数,无异于一根根稻草的堆加,终于能将骆驼压死。养成合理使用(?:…)括号的习惯。
宁简勿繁。将一条复杂的正则表达式拆分为两条或多条简单的正则表达式,编程难度会降低,运行效率会提 升。例如用来消除行首和行尾空白字符的正则表达式s/^\s+|\s+$//g;,其运行效率理论上要低于s/^\s+//g; s/\s+$//g; 。这个例子出自《精通正则表达式》第五章,书中对它的评论是“它几乎总是最快的,而且显然最容易理解”。既快又容易理解,何乐而不为?工作中我们还有其它 的理由要将C==(A|B)这样的正则表达式拆为A和B两条表达式分别执行。例如,虽然A和B这两种情况只要有一种能够击中所需要的文本模式就会成功匹 配,但是如果只要有一条子表达式(例如A)会产生误匹配,那么不论其它的子表达式(例如B)效率如何之高,范围如何精准,C的总体精准度也会因A而受到影 响。
巧妙定位。有时候,我们需要匹配的the,是作为单词的the(两边有空格),而不是作为单词一部分的t-h-e的有序排列(例如together中的the)。在适当的时候用上^,$,\b等等定位锚点,能有效提升找到成功匹配、淘汰不成功匹配的效率。

浙公网安备 33010602011771号