学习正则表达式
在写页面的时候,经常会对某些输入框进行一些限制,比如只能输入数字等。
这个时候,就用到了正则表达式。
所谓的正则表达式,就是用某种模式去匹配一类字符串的一个公式。
相信大家在大学的时候肯定学过形式语言与自动机、编译原理等课程,当时最深的印象就是正规文法与有限自动机的等价性,犹如天书啊。不过这种东西也是只有用过之后才会发现,其实没有那么深奥的,而且,一旦你弄懂它们,你就能把数小时辛苦而且易错的文本处理工作压缩在几分钟(甚至几秒钟)内完成,这个是不是很诱惑呢?
正则表达式由一些普通字符和一些元字符(metacharacters)组成。普通字符包括大小写的字母和数字,而元字符则具有特殊的含义。
不含元字符的的查找串,看上去就是一个普通的查找串。例如,正则表达式"testing"中没有包含任何元字符,它可以匹配"testing"和"123testing"等字符串,但是不能匹配"Testing"。
要想真正的用好正则表达式,正确的理解元字符是最重要的事情。
下表列出了所有的元字符和对它们的一个简短的描述。
|
元字符 |
|
描述 |
|
. |
匹配任何单个字符。例如正则表达式r.t匹配这些字符串:rat、rut、r t,但是不匹配root。 |
|
|
$ |
匹配行结束符。例如正则表达式weasel$ 能够匹配字符串"He's a weasel"的末尾,但是不能匹配字符串"They are a bunch of weasels."。 |
|
|
^ |
匹配一行的开始。例如正则表达式^When in能够匹配字符串"When in the course of human events"的开始,但是不能匹配"What and When in the"。 |
|
|
* |
匹配0或多个正好在它之前的那个字符。例如正则表达式.*意味着能够匹配任意数量的任何字符。 |
|
|
" |
这是引用府,用来将这里列出的这些元字符当作普通的字符来进行匹配。例如正则表达式"$被用来匹配美元符号,而不是行尾,类似的,正则表达式".用来匹配点字符,而不是任何字符的通配符。 |
|
|
[ ] |
匹配括号中的任何一个字符。例如正则表达式r[aou]t匹配rat、rot和rut,但是不匹配ret。可以在括号中使用连字符-来指定字符的区间,例如正则表达式[0-9]可以匹配任何数字字符;还可以制定多个区间,例如正则表达式[A-Za-z]可以匹配任何大小写字母。另一个重要的用法是“排除”,要想匹配除了指定区间之外的字符——也就是所谓的补集——在左边的括号和第一个字符之间使用^字符,例如正则表达式[^269A-Z] 将匹配除了2、6、9和所有大写字母之外的任何字符。 |
|
|
"< "> |
匹配词(word)的开始("<)和结束(">)。例如正则表达式"<the能够匹配字符串"for the wise"中的"the",但是不能匹配字符串"otherwise"中的"the"。 注意:这个元字符不是所有的软件都支持的。 |
|
|
"( ") |
将 "( 和 ") 之间的表达式定义为“组”(group),并且将匹配这个表达式的字符保存到一个临时区域(一个正则表达式中最多可以保存9个),它们可以用 "1 到"9 的符号来引用。 |
|
|
| |
将两个匹配条件进行逻辑“或”(Or)运算。例如正则表达式(him|her) 匹配"it belongs to him"和"it belongs to her",但是不能匹配"it belongs to them."。 注意:这个元字符不是所有的软件都支持的。 |
|
|
+ |
匹配1或多个正好在它之前的那个字符。例如正则表达式9+匹配9、99、999等。 注意:这个元字符不是所有的软件都支持的。 |
|
|
? |
匹配0或1个正好在它之前的那个字符。 注意:这个元字符不是所有的软件都支持的。 |
|
|
"{i"} |
匹配指定数目的字符,这些字符是在它之前的表达式定义的。例如正则表达式A[0-9]"{3"} 能够匹配字符"A"后面跟着正好3个数字字符的串,例如A123、A348等,但是不匹配A1234。而正则表达式[0-9]"{4,6"} 匹配连续的任意4个、5个或者6个数字字符。 注意:这个元字符不是所有的软件都支持的。 |
下面给出几个例子,并且来分析一下。
1)^[A-Za-z0-9]+$
这个表达式可以匹配任何由数字和26个英文字母组成的字符串。
^表示出这一行的开始,[A-Za-z0-9]匹配数字和26个英文字母(包括大小写),
[A-Za-z0-9]+可以匹配一个或多个数字和字母,$表示结束。是不是很简单?再来一个?
2)^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$
^\w[-._\w]*\w.?@\w[-._\w]*\w\.\w{2,4}$
这两个表达式都可以匹配email地址,但是两者又是不一样的。
3)^(news|http|ftp|https):\/\/[\w]+(\.[\w]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?$
这个表达式可以匹配url。
^(news|http|ftp|https):\/\/可以匹配诸如http://,ftp://这样的字符串,
[\w]+匹配多个字符,(\.[\w]+)+匹配.com,.aa.com之类的字符串,
([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?可以匹配一个或多个诸如查询条件之类的字符串。
所以,这个表达式可以匹配http://www.baidu,但是不能匹配http://www.这样的,
它甚至匹配http://docs.google.com/Doc?docid=dh9rqmq_30gb8x2v&hl=zh_CN#这么复杂的URL。
4)^((((1[6-9]|[2-9]\d)\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\d|3[01]))|(((1[6-9]|[2-9]\d)\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\d|30))|(((1[6-9]|[2-9]\d)\d{2})-0?2-(0?[1-9]|1\d|2[0-8]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29-))$
这个就非常厉害了,它可以匹配任意的YYYY-MM-DD格式的日期,基本上把闰年和2月等的情况都考虑进去了。来挑战一下吧。
(((1[6-9]|[2-9]\d)\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\d|3[01]))
可以匹配有31天的月份(从1600年开始)
(((1[6-9]|[2-9]\d)\d{2})-(0?[469]|1[1])-(0?[1-9]|[12]\d|30))
可以匹配有30天的月份(从1600年开始)
(((1[6-9]|[2-9]\d)\d{2})-0?2-(0?[1-9]|1\d|2[0-8]))
可以匹配2月份(从1600年开始)
(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29-)
可以匹配闰年的2月29号(从1600年开始)
以后各位在判断一个字符串是否是日期的时候又多了一个选择。呵呵。
好了,上面四个例子中只有第三个两个表达式我没有做出分析,你来分析一下如何???
浙公网安备 33010602011771号