PHP 正则 表达式 详解

PHP 正则表达式详解

正则表达式的简介

正则表达式的语法
正则表达式:描述了一种字符串匹配的模式,可以用来检查一个字符串是否行货某种子串,将匹配的子串做替换或者从某个串中取出符合某个条件的子串等

普通字符

普通字符:普通字符指包括没有显示指定为元字符的所有可打印或不可打印的字符,这包括所有大写或小写字母 、所有数字、所有标点符号或一些其他符号。

非打印字符

非打印字符也可以是正则表达式的组成部分,下表列出非打印字符的转义序列:
字符描述实例
\cx匹配由x指明的控制字符\cM 匹配一个Control - M 或者回车符。x的值必须为A-Z 或 a-z。否则,将c视为一个原义的 ‘c’字符
\f匹配一个换页符等价于 \xOc 和 \cL
\n匹配一个换行符等价于 \xOa 和 \cJ
\r匹配一个回车符等价于 \xOd 和 \xM
\s匹配任何空白字符包括空格、制表符、换页符 等价于[\f\n\r\t\v]。
\S匹配非空字符等价于[^\f\n\r\t\v]
\t匹配一个制表符等价于 \xO9 和\cI
\v匹配一个垂直制表符等价于 \xOb和 \cK

模式修正符

//修正符:i 不区分大小写的匹配;
//如:"/abc/i"可以与abc或aBC或ABc等匹配;
//修正符:g表示全局匹配
//修正符:m 将字符串视为多行,不管是那行都能匹配;
例://模式为:$mode="/abc/m";
//要匹配的字符串为:$str="bcefg5e\nabcdfe"
//注意其中\n,换行了;abc换到了下一行;
//$str和$mode仍可以匹配,修正符m使得多行也可匹配;
//修正符:s 将字符串视为单行,换行符作为普通字符;

例://模式为:$mode="/pr.y/";
//要匹配字符串为:$str="pr\ny";
//两者不可匹配; . 是除了换行以外的字符可匹配;
//修改下模式为:$mode="/pr.y/s";
//其中修正符s将\n视为普通字符,即不是换行;
//最后两者可以匹配;
//修正符:x 将模式中的空白忽略;
//修正符:A 强制从目标字符串开头匹配;

例://$mode="/abc/A";
//可以与$str="abcsdfi"匹配,
//不可以与$str2="sdsdabc"匹配;
//因为$str2不是以abc开头;
//修正符:D 如果使用$限制结尾字符,则不允许结尾有换行;

例://模式为:$mode="/abc$/";
//可以与最后有换行的$str="adshabc\n"匹配;
//元子符$会忽略最后的换行\n;
//如果模式为:$mode="/abc/D",
//则不能与$str="adshabc\n"匹配,
//修正符D限制其不可有换行;必需以abc结尾;
//修正符:U 只匹配最近的一个字符串;不重复匹配;

特殊字符

所谓特殊字符,就是一些有特殊含义的字符,类似于一个保留的关键字,下表列出了正则表达式的特殊字符
特别字符描述例子
$匹配输入字符串结尾的位置‘b$’则是匹配以b结尾的字符串
()标记一个子表达式的开始和结束位置,子表达式可以获取供以后使用‘(abc)’,则是匹配
*匹配前面子表达式的零次或多次‘a*’,则是匹配
+匹配前面的子表达式一次或多次‘a+’
.匹配除换行符 \n 之外的任何单字符
[ ]标记一个中括号表达式
匹配前面的子表达式零次或一次 ,或指明一个非贪婪限定符
\将下一个字符标记为特殊字符、或原义字符、或向后引用、或八进制转义符要匹配‘\’则需要‘\’
^匹配输入字符串的开始位置,在方括号内则是取反
{ }标记限定符的开始
|指明两项之间的一个选择

限定符

限定符用来指定正则表达式的一个给定组件必须要出现多次才能满足匹配。有 * 或 + 或 ? 或  {n} {n,} {n,m}共 6种

正则表达式的限定符有

字符描述实例
*匹配前面的子表达式零次或多次。‘zo*’ 则匹配‘z’以及‘zoo’,等价于{0,}
+匹配前面的子表达式一次或多次‘zo+’,则是匹配‘zo’以及‘zoo’,但是不能匹配‘z’相当于{1,}
{n}匹配前面的子表达式n次‘re{2}’,则是匹配‘bee’
{n,}匹配前面的子表达式至少n次
{n,m}n,m都为非负整数,其中m>=n,最少匹配n次,最多匹配m次‘a{1,3}’ 将匹配‘aab’和‘abbc’

注:

*、+和{}限定都是贪婪的,因为它们会尽可能多的匹配文字,只有在它们后面加上一个?就可以实现非贪婪或最小匹配

定位符

定位符将正则表达式固定到行首和行尾,限定符有‘$’,‘^’,‘\b’,‘\B’

选择

用圆括号将所有项括起来,相邻的选择项之间用|分割。但用圆括号有副作用,就是相关的匹配会被缓存,此时可以用?:放在第一个选项前消除这种副作用。其中?:是非捕获元之一,还有两个非捕获元是?= 和 ?!,前者为正向预查,在任何开始匹配圆括号内的正则表达式模式位置来匹配搜索字符串,后者则是负向预查,在任何不匹配该正则表达式模式的位置来匹配搜索字符串。

反向引用

对一个正则表达式模式或部分模式两边添加圆括号将导致相关匹配存储到一个临时的缓冲区中,所捕获的每个子匹配都按照在正则表达式模式中从左到右出现的顺序存储。

正则表达式- -元字符

元字符

正则表达式语言由两种基本字符类型组成:原义(正常)文本字符和元字符。元字符使正则表达式具有处理能力。所谓元字符就是指那些在正则表达式中具有特殊意义的专用字符,可以用来规定其前导字符(即位于元字符前面的字符)在目标对象中的出现模式。

常见元字符如下表

字 符描述实例
\将下一个字符标记为一个特殊字符、或一个原义字符、或一个 向后引用、或一个八进制转义符。‘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。
(pattern)匹配 pattern 并获取这一匹配。所获取的匹配可以从产生的 Matches 集合得到,在VBScript 中使用 SubMatches 集合,在JScript 中则使用 0 0 … 9 属性。要匹配圆括号字符,请使用 ‘(’ 或 ‘)’。
(?:pattern)匹配 pattern 但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用 “或” 字符 () 来组合一个模式的各个部分是很有用。例如, ‘industr(?:y
(?=pattern)正向预查,在任何匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如,’Windows (?=9598
(?!pattern)负向预查,在任何不匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如’Windows (?!9598
x|y匹配 x 或 y。例如,’zfood’ 能匹配 “z” 或 “food”。’(z
[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]。
\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正则表达式

preg_match
preg_match ( string $pattern , string $subject [, array &$matches [, int $flags = 0 [, int $offset = 0 ]]] ) 执行一个正则表达式匹配

pattern
要搜索的模式,字符串类型
subject
输入字符串
matches
如果提供了参数matches,它将被填充为搜索结果。 $matches[0]将包含完整模式匹配到的文本,$matches[1]将包含第一个捕获子组匹配到的文本,以此类推。
flags
flags可以被设置为以下标记值

preg_match_all
执行一个全局正则表达式匹配

<?php

$str =  'abcdaef34gaa';
$pattern = '/a/';

 preg_match_all($pattern, $str,$res);

var_dump($res);
结果:
array (size=1) 0 => 
array (size=4)
  0 => string 'a' (length=1)
  1 => string 'a' (length=1)
  2 => string 'a' (length=1)
  3 => string 'a' (length=1)

preg_replace

执行一个正则表达式的搜索和替换

  • preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )
  • pattern
    要搜索的模式。可以使一个字符串或字符串数组。
  • replacement
    用于替换的字符串或字符串数组。如果这个参数是一个字符串,并且pattern是一个数组,那么所有的模式都使用这个字符串进行替换。如果pattern和replacement都是数组,每个pattern使用replacement中对应的 元素进行替换。如果replacement中的元素比pattern中的少, 多出来的pattern使用空字符串进行替换
  • subject
    要进行搜索和替换的字符串或字符串数组
  • limit
    每个模式在每个subject上进行替换的最大次数。默认是 -1(无限)。
  • count
    如果指定,将会被填充为完成的替换次数。

    <?php
    $string = 'April 15, 2003';
    $pattern = '/(\w+) (\d+), (\d+)/i';
    $replacement = '${1}1,$3'; // $3指的是第三个(\d+)
    echo preg_replace($pattern, $replacement, $string);
    ?>  
    结果:
    April1,2003
    
    **基于数组替换**
    
    <?php
    $string = 'The quick brown fox jumped over the lazy dog.';
    $patterns = array();
    $patterns[0] = '/quick/';
    $patterns[1] = '/brown/';
    $patterns[2] = '/fox/';
    $replacements = array();
    $replacements[2] = 'bear';
    $replacements[1] = 'black';
    $replacements[0] = 'slow';
    echo preg_replace($patterns, $replacements, $string);
    ?> 
    

preg_quote

转义正则表达式字符
注:正则表达式特殊字符有: . \ + ? [ ^ ] $ ( ) { } = ! < > | : -*
preg_quote ( string \$str [, string \$delimiter = NULL ] )

  • str
    输入字符串
  • delimiter
    如果指定了可选参数 delimiter,它也会被转义。这通常用于 转义PCRE函数使用的分隔符。 /是最通用的分隔符。

    <?php
    $keywords = '$40 for a g3/400';
    $keywords = preg_quote($keywords, '/');
    echo $keywords; // 返回 \$40 for a g3\/400
    ?>  
    

preg_split
通过一个正则表达式分隔字符串
preg_split ( string $pattern , string $subject [, int $limit = -1 [, int $flags = 0 ]] )

  • pattern
    用于搜索的模式,字符串形式。
  • subject
    输入字符串
  • limit
    如果指定,将限制分隔得到的子串最多只有limit个,返回的最后一个 子串将包含所有剩余部分。limit值为-1, 0或null时都代表”不限制”, 作为php的标准,你可以使用null跳过对flags的设置。
  • flags
    可以是任何下面标记的组合(以位或运算 | 组合)

    <?php
    $str = 'string';
    $chars = preg_split('//', $str, -1, PREG_SPLIT_NO_EMPTY);
    print_r($chars);
    ?> 
    结果:
    Array
    (
        [0] => s
        [1] => t
        [2] => r
        [3] => i
        [4] => n
        [5] => g
    )
    
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值