正则表达式 小结 经典解决方案[2]
匹配重复匹配
正则表达式中有一些用于重复匹配某些原子的元字符:“?”、“*”、“+”。他们主要的区别是重复匹配的次数不同。
元字符“?”:表示0次或1次匹配紧接在其前的原子。
例如:/colou?r/匹配“colour”或“color”。
元字符“*”:表示0次、1次或多次匹配紧接在其前的原子。
例如:/zo*/可以匹配z、zoo
元字符“+”:表示1次或多次匹配紧接在其前的原子。
例如:/go+gle/匹配“gogle”、“google”或“gooogle”等中间含有多个o的字符串。
元字符“{}”准确地指定原子重复的次数,指定所匹配的原子出现的次数。
“{m}”表示其前原子恰好出现m次;
“{m,n}”表示其前原子至少出现m次,至多出现n次;
“{m,}”表示其前原子出现不少于m次。
例如:
/zo{1,3}m/只能匹配字符串“zom”、“zoom”、或“zooom”。
/zo{3}m/只能匹配字符串“zooom”
/zo{3,}m/可以匹配以 “z” 开头,“m”结束,中间至少为3个“o”的字符串。
/bo{0,1}u/可以匹配字符串“bought a butter” 中的“bou”和“bu”,等价于bo?u。
匹配任何一个字符
元字符“.”匹配除换行符外任何一个字符,相当于[^\n](Unix系统)或[^\r\n](windows系统)。
例如:/pr.y/可以匹配的字符串“prey”、“pray”或“pr%y”等。
通常可以使用“.*”组合来匹配除换行符外的任何字符。在一些书籍中也称其为“全匹配符” 或 “单含匹配符”。
例如:
/.+/也可以完成类似的匹配功能所不同的是其至少匹配一个字符。
/^a.+z$/匹配“a%z”不匹配字符串“az”。
/^a.*z$/表示可以匹配字母“a”开头,字母“z”结束的任意不包括换行符的字符串。
php正则表达式涉及的函数:
preg_match()
preg_match_all()
preg_replace()
preg_split()
SQL语句正则表示式
POSIX风格预定义的正则表达式的字符类:
[[:alnum:]] 字母和数字字符
[[:alpha:]] 大小写字母
[[:lower:]] 小写字母
[[:upper:]] 大写字母
[[:digit:]] 数字0-9
[[:xdigit:]] 十六进制数字
[[:punct:]] 标点符号,包括上档键!@
[[:blank:]] TAB制表符和空格
例子:
SELECT * FROM data t WHERE t.f002 REGEXP "^[[:digit:]]+$"; 查找所有f002字段为整形的值
SELECT * FROM data t WHERE t.date_str REGEXP "abril-.*[[:alpha:]]+"; 查找所有date_str符合abril-开头的一些字符串
常用正则:
"^\d+$":非负整数(正整数 + 0)
"^[0-9]*[1-9][0-9]*$":正整数
"^((-\d+)|(0+))$":非正整数(负整数 + 0)
"^-[0-9]*[1-9][0-9]*$":负整数
"^-?\d+$":整数
"^\d+(\.\d+)?$":非负浮点数(正浮点数 + 0)
"^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$":正浮点数
"^((-\d+(\.\d+)?)|(0+(\.0+)?))$":非正浮点数(负浮点数 + 0)
"^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$":负浮点数
"^(-?\d+)(\.\d+)?$":浮点数
"^[A-Za-z]+$":由26个英文字母组成的字符串
"^[A-Z]+$":由26个英文字母的大写组成的字符串
"^[a-z]+$":由26个英文字母的小写组成的字符串
"^[A-Za-z0-9]+$":由数字和26个英文字母组成的字符串
"^\w+$":由数字、26个英文字母或者下划线组成的字符串
"^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$":email地址
\b(25[0-5] |2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}25[0-5] |2[0-4]\d|1\d{2}|[1-9]\d|[1-9])\b :IP地址0.0.0.1-255.255.255.255
"^[a-zA-z]+://(\w+(-\w+)*)(\.(\w+(-\w+)*))*(\?\S*)?$":url
邮件地址最基本的格式可以看作是 <用户名@域名>。对于用户名,各个ISP没有统一的标准,除了数字和字母外,有的允许有<_>,有的允许有<.>,也有的两者皆可,或者允许其他的特殊字符。对此我们只能根据具体的情况加以判断。
文中假设除字母和数字外还允许<.><_>,<.><_>不能出现在首末位,<.><_>不能相连。域名中各段除数字和字母外只允许出现<->,且<->不能出现在首位和末位,各段用<.>连接。我们还可从域名得知最后一段大于一位且只有字母。
下面我们就可以依据以上假设写出如下表达式来判断是否该串是一个邮件地址:
^([a-z0-9A-Z]+[-|\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\.)+[a-zA-Z]{2,}$
稍作解释:
^:匹配开始
([a-z0-9A-Z]+[-|\.]?)+:数字或字母>1位 +
<->或<.>,以上组合重复1次以上
[a-z0-9A-Z]:用户名以数字或字母结尾
@:匹配<@>
(
[a-z0-9A-Z]+:匹配多位数字或字母
(-[a-z0-9A-Z]+)?:匹配
-加多位数字或字母
0次或1次
\.:匹配<.>
)+:匹配括号中内容多次
[a-zA-Z]{2,}:匹配字母2次以上
$:匹配结尾