利用正则表达式将字符串分组处理
2010-08-29 19:58
441 查看
正则表达式在脚本语言中所起的作用是不言而喻的,熟练掌握正则表达式,对于每个脚本开发人员都至关重要,下面,我以近期工作中遇到的实际例子来介绍如何使用正则表达式在对字符串进行处理。
需求:
有一个字符串(如下所示),其特点是都多个[]括起,每个[]后用逗号隔开,结尾没有逗号,[]中的字符串也用逗号隔开
要求将此字符串以[]为单位分割成N个小数组。
处理的方法如下所示:
重点在于preg_match_all函数的第一个参数:模式
我们来看这个模式:
//[(.+?)/]/i
//i 是定界符(delimiter
),使用preg_match此类的函数一般都这么写,两个反斜杠//中间的部分为模式内容,i表示不区分大小写。
再来看这部分
/[(.+?)/]
由于方括号[]属于元字符,我们需要将其转义后才能匹配方括号[]本身。
注意了,方括号/[/]里面的这部分内容是重点中的重点,也是难点。
(.+?)
圆括号()表示把这里面的内容 .+?
作为一个整体放入内存中识别
点.
表示匹配一个除换行符以外的任意字符
下面来讲解最最重要的概念(当然是跟 +?
息息相关的了!):
贪婪与懒惰
当正则表达式中包含能接受重复的限定符时,通常的行为是(在使整个表达式能得到匹配的前提下)匹配尽可能多
的字符。以这个表达式为例:a.*b
,它将会匹配最长的以a开始,以b结束的字符串
。如果用它来搜索aabab
的话,它会匹配整个字符串aabab
。这被称为贪婪
匹配
。
有时,我们更需要懒惰
匹配
,也就是匹配尽可能少
的字符。前面给出的限定符都可以被转化为懒惰匹配模式,只要在它后面加上一个问号?
。这样.*?
就意味着匹配任意数量的重复,但是在能使整个匹配成功的前提下使用最少的重复
。现在看看懒惰版的例子吧:
a.*?b
匹配最短的,以a开始,以b结束的字符串
。如果把它应用于aabab
的话,它会匹配aab(第一到第三个字符)
和ab(第四到第五个字符)
。
为什么第一个匹配是aab(第一到第三个字符)而不是ab(第二到第三个字符)?简单地说,因为正则表达式有另一条规则,比懒惰/贪婪规则的优先级更高:最先开始的匹配拥有最高的优先权
——The match that begins earliest wins。
下面给出懒惰限定符参考表(摘自《正则表达式30分钟入门教程》)
懒惰限定符
有的读者会问了,为什么点.后面跟的是加号+而不是星号*呢?
因为我们方括号[]里面是有内容的,如果修改为星号*,表示匹配前面表达式的0次~多次,即便方括号[]里面是空的,这样的也会被匹配到,当然这样的字符串不是我们需要的。
希望能通过这个例子,你对正则表达式有了更为深入的了解。
需求:
有一个字符串(如下所示),其特点是都多个[]括起,每个[]后用逗号隔开,结尾没有逗号,[]中的字符串也用逗号隔开
要求将此字符串以[]为单位分割成N个小数组。
<?php $a = '["1","abc","0"],["2","def","0"],["3","ghi","0"]'; ?>
处理的方法如下所示:
<?php preg_match_all("//[(.+?)/]/i",$a,$arr); var_dump($arr[1]); ?>
重点在于preg_match_all函数的第一个参数:模式
我们来看这个模式:
//[(.+?)/]/i
//i 是定界符(delimiter
),使用preg_match此类的函数一般都这么写,两个反斜杠//中间的部分为模式内容,i表示不区分大小写。
再来看这部分
/[(.+?)/]
由于方括号[]属于元字符,我们需要将其转义后才能匹配方括号[]本身。
注意了,方括号/[/]里面的这部分内容是重点中的重点,也是难点。
(.+?)
圆括号()表示把这里面的内容 .+?
作为一个整体放入内存中识别
点.
表示匹配一个除换行符以外的任意字符
下面来讲解最最重要的概念(当然是跟 +?
息息相关的了!):
贪婪与懒惰
当正则表达式中包含能接受重复的限定符时,通常的行为是(在使整个表达式能得到匹配的前提下)匹配尽可能多的字符。以这个表达式为例:a.*b
,它将会匹配最长的以a开始,以b结束的字符串
。如果用它来搜索aabab
的话,它会匹配整个字符串aabab
。这被称为贪婪
匹配
。
有时,我们更需要懒惰
匹配
,也就是匹配尽可能少
的字符。前面给出的限定符都可以被转化为懒惰匹配模式,只要在它后面加上一个问号?
。这样.*?
就意味着匹配任意数量的重复,但是在能使整个匹配成功的前提下使用最少的重复
。现在看看懒惰版的例子吧:
a.*?b
匹配最短的,以a开始,以b结束的字符串
。如果把它应用于aabab
的话,它会匹配aab(第一到第三个字符)
和ab(第四到第五个字符)
。
为什么第一个匹配是aab(第一到第三个字符)而不是ab(第二到第三个字符)?简单地说,因为正则表达式有另一条规则,比懒惰/贪婪规则的优先级更高:最先开始的匹配拥有最高的优先权
——The match that begins earliest wins。
下面给出懒惰限定符参考表(摘自《正则表达式30分钟入门教程》)
代码/语法 | 说明 |
---|---|
*? | 重复任意次,但尽可能少重复 |
+? | 重复1次或更多次,但尽可能少重复 |
?? | 重复0次或1次,但尽可能少重复 |
{n,m}? | 重复n到m次,但尽可能少重复 |
{n,}? | 重复n次以上,但尽可能少重复 |
因为我们方括号[]里面是有内容的,如果修改为星号*,表示匹配前面表达式的0次~多次,即便方括号[]里面是空的,这样的也会被匹配到,当然这样的字符串不是我们需要的。
希望能通过这个例子,你对正则表达式有了更为深入的了解。
相关文章推荐
- 用正则表达式处理字符串中的分组问题
- BCB利用VBScript正则表达式处理字符串
- C#程序中利用正则表达式对字符串分组并获取组值
- 利用正则表达式快捷处理字符串
- 利用正则表达式将字符串分组示例代码
- 二:字符串和正则表达式_字符串处理
- 利用正则表达式去除字符串前后空格(原创)
- 字符串处理函数sscanf的使用(某些程度上替代正则表达式,很强大)
- JavaScript利用正则表达式替换字符串中的内容
- 利用正则表达式 替换字符串中多个 URL
- c# 使用正则表达式对字符串进行处理
- 字符串处理(正则表达式、NSScanner扫描、CoreParse解析器)-备用
- 包装类、字符串方法、时间处理、正则表达式
- 利用正则表达式选取出字符串中存在的链接
- 利用java正则表达式来解析并获取指定的字符串
- 利用正则表达式排除特定字符串
- 字符串处理—正则表达式和模式匹配
- C# 利用正则表达式进行忽略大小写的字符串替换的应用
- 【Web前端】Js利用正则表达式提取字符串
- 字符串处理:ABAP中的正则表达式