目录

PCRE

PCRE 库是一个实现了与 perl 5 在语法和语义上略有差异(详见下文)的正则表达式模式匹配功能的函数集。当前的实现对应于 perl 5.005。

正则表达式是一个从左到右匹配目标字符串的模式。大多数字符自身就代表一个匹配它们自身的模式。

PCRE除了要了解正则表达式外,有一些特殊的知识点:

分隔符

当使用 PCRE 函数的时候,模式需要由分隔符闭合包裹。分隔符可以使任意非字母数字、非反斜线(通常说的转义符\)、非空白字符。

经常使用的分隔符是正斜线(/)、hash符号(#) 以及取反符号(~)。

比如以下都是合法的:

/foo bar/
#^[^0-9]$#
+php+
%[a-zA-Z0-9_-]%

除了上面提到的分隔符,也可以使用括号样式的分隔符,左括号和右括号分别作为开始和结束分隔符。

{this is a pattern}

元字符

参考:正则表达式

子组/子模式

子组通过圆括号()分隔界定,并且它们可以嵌套。将一个模式中的一部分标记为子组(子模式)主要是来做两件事情:

  • 将可选分支局部化。比如,模式cat(arcat|erpillar|)匹配 “cat”, “cataract”, “caterpillar” 中的一个,如果没有圆括号的话,它匹配的则是 “cataract”, “erpillar” 以及空字符串。

  • 将子组设定为捕获子组。当整个模式匹配后,目标字符串中匹配子组的部分将会通过 pcre_exec() 的 ovector 参数回传给调用者。左括号从左至右出现的次序就是对应子组的下标(从 1 开始),可以通过这些下标数字来获取捕获子模式匹配结果。 下标 0 获取的是整个字符串。

常用模式修饰符

i (PCRE_CASELESS),如果设置了这个修饰符,模式中的字母会进行大小写不敏感匹配

s (PCRE_DOTALL)如果设置了这个修饰符,模式中的点号元字符匹配所有字符,包含换行符。如果没有这个修饰符,点号不匹配换行符。

区别于POSIX函数

自 PHP 5.3.0起, POSIX 正则表达式扩展被废弃。请尽量使用PCRE函数,也就是preg_前缀的函数:

POSIX PCRE
ereg_replace() preg_replace()
ereg() preg_match()
eregi_replace() preg_replace()
eregi() preg_match()
split() preg_split()
spliti() preg_split()
sql_regcase() 无对等函数

PCRE函数

  • preg_match — 执行匹配正则表达式

    搜索subject与pattern给定的正则表达式的一个匹配。

    preg_match( string $pattern, string $subject[, array &$matches[, int $flags = 0[, int $offset = 0]]] ) : int
    

    pattern:要搜索的模式,字符串类型。

    subject:输入字符串。

    matches:如果提供了参数matches,它将被填充为搜索结果。 $matches[0]将包含完整模式匹配到的文本, $matches[1] 将包含第一个捕获子组匹配到的文本,以此类推。

    flags:具体使用参考官方文档,比较少使用。

    offset:通常,搜索从目标字符串的开始位置开始。可选参数 offset 用于指定从目标字符串的某个位置开始搜索(单位是字节)。

    注意:preg_match()返回 pattern 的匹配次数。它的值将是0次(不匹配)或1次,因为preg_match()在第一次匹配后将会停止搜索。preg_match_all()不同于此,它会一直搜索subject 直到到达结尾。如果发生错误preg_match()返回 FALSE。

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

    搜索subject中所有匹配pattern给定正则表达式的匹配结果并且将它们以flag指定顺序输出到matches中。

    在第一个匹配找到后, 子序列继续从最后一次匹配位置搜索。

    与preg_match函数是相似的,区别在于preg_match_all()不同于此,它会一直搜索subject 直到到达结尾。

    preg_match_all("|<[^>]+>(.*)</[^>]+>|U",
        "<b>example: </b><div align=left>this is a test</div>",
        $out, PREG_PATTERN_ORDER);
    echo $out[0][0] . ", " . $out[0][1] . "\n";
    echo $out[1][0] . ", " . $out[1][1] . "\n";
    

    输出:

    <b>example: </b>, <div align=left>this is a test</div>
    example: , this is a test
    

    可以通过flag参数调整matchs多维数组返回元素的结构: flag默认为PREG_PATTERN_ORDER,我们还可以设置PREG_SET_ORDER,则输出:

    <b>example: </b>, example: 
    <div align=left>this is a test</div>, this is a test
    
    
  • preg_grep — 返回匹配模式的数组元素

    返回给定数组input中与模式pattern 匹配的元素组成的数组.。数组的key使用匹配元素在原数组的key。

    preg_grep( string $pattern, array $input[, int $flags = 0] ) : array
    

    匹配数组中是浮点数的元素:

    $array = ["1.2","3",'45','6.7','8.0','9'];
    $fl_array = preg_grep("/^(\d+)?\.\d+$/", $array);
    print_r($fl_array);
    

    输出:

    Array
    (
        [0] => 1.2
        [3] => 6.7
        [4] => 8.0
    )
    
    
  • preg_split — 通过一个正则表达式分隔字符串

    preg_split( string $pattern, string $subject[, int $limit = -1[, int $flags = 0]] ) : array
    

    通过一个正则表达式分隔给定字符串。返回一个使用 pattern 边界分隔 subject 后得到的子串组成的数组, 或者在失败时返回 FALSE。

    如果指定limit参数,将限制分隔得到的子串最多只有limit个,返回的最后一个子串将包含所有剩余部分。limit值为-1, 0或null时都代表"不限制”。

    注意:如果不需要正则表达式功能,可以有更快(并且更简单)的选择比如 explode() 或 str_split()。

    flag设置为PREG_SPLIT_NO_EMPTY可以用于过滤空串。

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

    preg_replace( mixed $pattern, mixed $replacement, mixed $subject[, int $limit = -1[, int &$count]] ) : mixed
    

    搜索 subject 中匹配 pattern 的部分,以 replacement 进行替换。

    参数:replacement

    用于替换的字符串或字符串数组。如果这个参数是一个字符串,并且 pattern 是一个数组,那么所有的模式都使用这个字符串进行替换。如果 pattern 和 replacement 都是数组,每个 pattern 使用 replacement 中对应的元素进行替换。如果 replacement 中的元素比 pattern 中的少,多出来的 pattern 使用空字符串进行替换。

    $string = 'The quick brown brown fox jumps 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);//输出:The bear black black slow jumps over the lazy dog.
    
    //ksort($replacements);
    //ksort($patterns);
    //这里注意两个数组元素排序,并不是匹配patterns[0]并替换replaces[0],如果没有ksort的操作,将会是替换replaces[2]。注意数组元素的物理顺序。
    //echo preg_replace($patterns, $replacements, $string);//输出:The slow black black bear jumps over the lazy dog.
    
    $string = 'Mayl 10, 2020';
    $pattern = '/(\w+) (\d+), (\d+)/i';
    $replacement = '${1}1,$3';
    echo preg_replace($pattern, $replacement, $string);
    //输出:Mayl1,2020
    
  • preg_replace_callback — 执行一个正则表达式搜索并且使用一个回调进行替换

    这个函数的行为除了可以指定一个 callback 替代 replacement 进行替换字符串的计算,其他方面等同于 preg_replace()。

  • preg_replace_callback_array — Perform a regular expression search and replace using callbacks

  • preg_filter — 执行一个正则表达式搜索和替换

    preg_filter()等价于preg_replace() 除了它仅仅返回(可能经过转化)与目标匹配的结果。

  • preg_quote — 转义正则表达式字符

    preg_quote()需要参数 str 并向其中每个正则表达式语法中的字符前增加一个反斜线。 这通常用于你有一些运行时字符串需要作为正则表达式进行匹配的时候。

    正则表达式特殊字符有: . \ + * ? [ ^ ] $ ( ) { } = ! < > | : - #

    注意 / 不是正则表达式特殊字符。

  • preg_last_error — 返回最后一个PCRE正则执行产生的错误代码

  • preg_last_error_msg — 返回最后一次执行PCRE regex的错误消息

    成功时返回错误消息,如果没有发生错误,则返回“No error”。当然这个函数需要php8之后才支持。

POSIX正则函数

该特性在PHP 5.3.0中已弃用,在PHP 7.0.0中已删除。

POSIX的相关函数都可以通过PCRE函数来代替:

POSIX PCRE
ereg_replace() preg_replace()
ereg() preg_match()
eregi_replace() preg_replace()
eregi() preg_match()
split() preg_split()
spliti() preg_split()
sql_regcase() 无对等函数