描述字符串排列模式的一种自定义语法规则
如果可以使用字符串函数处理的任务 就不要使用正则
正则表达式 就是通过构建具有特定规则的模式,与输入的字符信息比较 在进行 分割 匹配 查找 替换 等工作
正则表达式 也是一个字符串
由具有特殊意义的字符串组成的字符
具有一定的编写规则 也是一种模式
可以把正则表达式看做是一种编程语言(是用一些特殊字符按照规则 编写出一个字符串 然后形成一种模式 --- 正则表达式)
waring:
如果正则表达式 不和函数一起使用,那么他就是一个字符串 如果将正则表达式放入到某个函数中使用 才能发挥出正则表达式的作用
用到分割函数中 就可以用这个去分割
用到替换函数中 就可以用这个去替换
用到匹配函数中 就可以用这个去匹配
在php中有两套php正则表达式
POSIX 扩展正则表达式函数 ereg_
perl 兼容的正则表达式函数 preg_
这两套函数的功能一样
正则表达式如何编写
1. 定界符 //
除了字母 数字 和正斜线 \ 以外的任何字符都可以是定界符 比如 || // {} ## !!
2. 原子 img \s .
一个正则表达式 可以没有元字符 但是必须至少包含一个原子
只要一个正则表达式可以单独使用的字符 就是原子
所有打印字符和费打印字符都是原子
如果有些元字符 想作为原子使用 统统使用 \ 转义字符转义
3. 元字符 * ?
元字符是一个特殊的字符 是用来修饰原子用的 不可以单独出现
4. 模式修正符 I U
/原子和元字符/模式修饰符
========================================
【原子】
\d 代表任意一个数字
\D 任意一个除了数字之外的字符
\s 匹配任意一个空白字符 空格 回车 \n 换行 \r
\S 匹配任意一个非空白
\w 匹配任意一个 a-zA-Z0-9_
\W 除了a-zA-Z0-9_之外的字符
[] 匹配[]中的任何一个原子 [12345] 里面的正则是或的关系
里面的正则元字符没意义 都是当做字符串来表示
里面只能单独匹配一个原子 不能匹配多个
[^ ] 表示取反
[^] 除了[]里面的所原子之外的字符 取反的意思 [^a-z123]
【元字符】
* 表示本修饰原子的前面的字符可以出现0次或者多次
+ 表示前面的字符可以出现1次或者多次
. 表示任意一个字符 除了换行符
^ 表示开头必须是前面的字符
$ 表示必须以前面的字符结尾
? 表示前面的字符可以出现0次或者1次
| 或者的关系
{} 自定义前面原子出现的次数 {5} 5次 {1,} 最少1次 {1,3} 1到3次
\b 匹配边界 两边如果有边界
\B 匹配非边界
() 作为大原子使用 括号里面的集合 可以看成一个大原子
1. (abc)+ 意思是 abcabcabc 这样
2. (a|b) 改变优先级 ()里面优先级高
3. 作为子模式使用
$reg = "/3+(abc)(t)/";
$string = "333abct";
if(preg_match($reg,$string,$arr))
结果是
Array ( [0] => 333abct [1] => abc [2] => t )
4. 反向引用
取出子模式 再作为正则表达式的一部分 如果是preg_replace 可以将子模式取出 在被替换的字符串使用
\1 取第一个子模式 。。。。\2\3\4\5
注意 如果是双引号 那必须是\\ 单引号 就是 \
5. 取消子模式
如果只是想用个括号 并不是子模式 可以这么用 (?:) 在括号最前面使用?: 就可以取消这个子模式
【修饰符】
在定界符后面写模式修正符号
可以一次使用一个也可以使用多个
对正则表达式调优用的 也可以说是对正则表达式的扩展
i 不区分大小写
m 匹配多行 ^..$ 多行后任何一行都可以用正则表达式规则套下
s 设置这个.匹配换行
x 表示正则表达式中的空白忽略不计 不是字符串里面的
e 执行php代码
A === ^
Z === $
g 执行一个全局的匹配,简而言之,就是找到所有的匹配 默认只找到一条
/u 表示按unicode(utf-8)匹配(主要针对多字节比如汉字)
U 正则表达式本身就比较贪婪 如果不开启U 正则表达式就会匹配到最后一个
禁止贪婪还可以加个? 一样可以禁止贪婪 .*? 如果两个同时出现 那么就会再次开启贪婪模式
正则表达式要转义的字符
. \ + * ? [ ^ ] $ ( ) { } = ! < > | : - ‘ “
取反
\W 匹配任意不是字母,数字,下划线,汉字的字符
\S 匹配任意不是空白的字符
\D 匹配任意非数字的字符
\B 匹配不是单词开头或者结束的字符
[^x] 匹配除了X以外的字符
[^aeiou] 匹配除了aeiou这几个字母以外的任意字符
分组、后向引用
从左往右 以分组的左括号开始 第一个出现的分组是1 第二个是2 以此类推
分组 0 对应整个正则表达式
分组号分配要从左往右 扫描两次 第一次是只给未命名的分组分配 第二次给命名分组分配 因此所有命名组的组号都大于未命名组的
可以使用 (:? ) 来剥夺一个分组对分组号的分配权
可以使用 (?) (?'name') 来自定义组名
(gwyy) 匹配 gwyy 并且捕获文本到自动命名的组里
(?gwyy) 匹配gwyy 并且把捕获到的文本命名为name组里 也可以写 (?'name' gwyy)
(?:gwyy) 匹配gwyy 不捕获文本 也不分配组号
(?<=gwyy) 匹配gwyy前面的位置
比如说 gwyyaaa 会返回 aaa
(?=gwyy) 匹配 gwyy 后面的位置
比如说 aaagwyy 会返回出 aaa
(?!gwyy) 匹配后面跟的不是gwyy的位置
(?
(?#gwyy) 注释
禁止贪婪
*? 重复任意次 但尽可能少重复
+? 重复一次或者多次 但是尽可能少重复
?? 重复零次或者1次 尽可能少重复
{n,m}? 重复N到M次 尽可能少重复
{n,}? 重复n次以上 尽可能少重复
Demo:
^\s+$ 用户名不能为空
[1-9][0-9]{4,12} 匹配腾讯QQ
(http|https):\/\/(\w)*.(\w)+.(\w)+
采集HTML 最好 不要用 .* 而是用 \s\S
$patth = '/\s+([\s\S]*)<\/a><\/span>\s+\[(\d+\-\d+)\]/U';
因为HTML会有回车符 和换行符
========================================================
这个函数是正则表达式匹配函数
preg_match(规则,要匹配的字符串,匹配到的结果集数组,返回数组的模式);
如果匹配成功就返回 true 否则返回 false
匹配到的结果集 第一个是所有的大模式所有的信息 剩下的是按照顺序的一个一个小的子模式
第三个是一个数组
可选,存储匹配结果的数组, $matches[0] 将包含与整个模式匹配的文本,$matches[1] 将包含与第一个捕获的括号中的子模式所匹配的文本,以此类推
比如说 有2个() 那么 数组0是所有的()集合 其他的 1、2、3 是每个() 里面的具体属性
例子
[php] view plaincopy
- Array
- (
- [0] => Array
- (
- [0] => http://bbs.thmz.com/thread-1931127-1-1.html
- [1] => http://bbs.thmz.com/thread-1931127-1-1.html
- )
- [1] => Array
- (
- [0] => http
- [1] => http
- )
- [2] => Array
- (
- [0] => ://bbs.thmz.com/thread-1931127-1-1.html
- [1] => ://bbs.thmz.com/thread-1931127-1-1.html
- )
- )
preg_match_all(规则,要匹配的字符串,匹配到结果数组) 匹配多次 这次的数组是多维数组
preg_match_all 和 U 的区别一个是匹配一个表达式多次 还有一个是 一个表达式中 所匹配的单位匹配到最近成功的
第四个参数
PREG_PATTERN_ORDER 默认 结果排序为$matches[0]保存完整模式的所有匹配, $matches[1]保存第一个子组的所有匹配, 以此类推.
PREG_SET_ORDER 结果排序为$matches[0]包含第一次匹配得到的所有匹配(包含子组), $matches[1]是包含第二次匹配到的所有匹配(包含子组)的数组, 以此类推.
函数
字符串的匹配和查找
preg_match(正则表达式,字符串,返回结果集)
字符串函数有个
str_repace(替换成的结果,要替换的字符串,源字符串,计算替换几次);
str_replace(字符串,字符串,字符串)
str_replace(数组,字符串,字符串);
str_replace(array,array,string);
正则表达式的替换
preg_replace('匹配内容','替换成什么内容','源','限制替换次数');
但是 正则表达式的子参数 可以用到第二个参数里面
[php] view plaincopy
- $rel = "/(\w+)/";
- $str = "PHP 独特的语法混合了 C、Java、Perl 以及 PHP 自创的语法。 ";
- $n = preg_replace($rel,'$1',$str);
- echo $n;
这样就会把所有的 a-z0-0_ 全部替换成了红色
第二个参数如果调用正则表达式里面的() 你可以用 \1 也可以用 $1
第二个参数是函数的话 要加个修饰符 e 执行php代码
[php] view plaincopy
- $rel = "/(\w+)/e";
- $str = "PHP 独特的语法混合了 C、Java、Perl 以及 PHP 自创的语法。 ";
- $n = preg_replace($rel,'"".strtoupper("$1").""',$str);
- echo $n;
还可以在前两个参数中 都使用数组 这样就能同时替换多个了 下面是个ubb代码替换
[php] view plaincopy
- $ubbcode = array(
- '/\[b\](.*)\[\/b\]/U',
- '/\[u\](.*)\[\/u\]/U',
- '/\[i\](.*)\[\/i\]/U',
- '/\[del\](.*)\[\/del\]/U',
- '/\[color=#(\w{6})\](.*)\[\/color\]/U',
- '/\[size=(\d{1,})px\](.*)\[\/size\]/U'
- );
- $htmls = array(
- '$1','$1','$1','
$1', - '$2',
- '$2'
- );
- $str ="HTML3.0规范是由[del]当时刚成立的W3[/del]C于1995年3月提出,提供了很多新的特性,例如表格、文字绕排和复杂数学元素的显示。[color=#FFCC00]虽然它是被设计用[/color]来兼容2.0版本的,但是[b]实现这个标准的工作在当[/b]时过于复杂,在草案于1995年9月过期时,标准开发也因为缺乏浏览器支持而中止了。3.1版从未被正式提出,而下一个[i]被提出的版本是[/i]开发代号为Wilbur的HTML 3.2,去掉了大部分3.0中的新特性,但是[u]加入了很[/u]多特定浏览器,例如Netscape和Mosaic的元素和属性。HTML对数学公[size=24px]式的支持最后成为[/size]另外一个标准MathML。";
- $n = preg_replace($ubbcode,$htmls,$str);
- echo $n;
preg_replace_callback 执行一个正则表达式搜索并且使用一个回调进行替换
分割一个字符串成数组 比原生的explode 更强大
[php] view plaincopy
- $a = "127.0,0?1";
- print_r(preg_split('/[.,?]/',$a));
在一个数组里面匹配一组相同的字符,返回一个新数组
[php] view plaincopy
- $a = array('aa bb','cc','dd','e e ');
- print_r(preg_grep('/\s+/',$a));
preg_quote 转义正则表达式字符 不用你手工转义了
==============================================================
匹配$_str 返回一个数组 给 $_new_str
返回数组
0位 表示所有结果
1位 表示第一个子结果
2位 表示第二个子结果
preg_match('//',$_str,$_new_str);
匹配全部
preg_match_all('//',$_str,$_new_str);
反向引用
/(\d)\1(\d)\2/
如果第一个是一个数字 那么 \1这个位置就是一个反向引用 要求第一次出现的数字 在 \1那里继续出现一次
\1 就代表第一个()里面的引用
如果还有一个的话 就是第二个值表达式的内容在\2出现
可以捕获很多值表达式 也许是99个也许是100多个
捕获
/(\d)\1(\d)\2/ 如果不是在正则表达式里用 就用 $1 $2 来捕获