preg_grep
array preg_grep ( string $pattern , array $input [, int $flags = 0 ] )
参数flags: If set to PREG_GREP_INVERT, this function returns the elements of the input array that do not match the given
pattern
.
<?php
$array=array(1.23,'12.32','23.a','.23');
$fl_array = preg_grep("/^(\d+)?\.\d+$/", $array,1);
var_dump($fl_array);
/********返回
array(1) {
[2] =>
string(4) "23.a"
}
********/
preg_quote
string preg_quote ( string $str [, string $delimiter = NULL ] )
preg_quote() 需要参数
str
并向其中 每个正则表达式语法中的字符前增加一个反斜线。 这通常用于你有一些运行时字符串 需要作为正则表达式进行匹配的时候。$delimiter 参数可以自主添加需进行转义的字符或字符串。
正则表达式特殊字符有: . \ + * ? [ ^ ] $ ( ) { } = ! < > | : -`
preg_match
int preg_match ( string $pattern , string $subject [, array &$matches [, int $flags = 0 [, int $offset = 0 ]]] )
<?php
$subject = "abcdef";
$pattern = '/def/';
preg_match($pattern, $subject, $matches);
print_r($matches);
/********返回
Array
(
[0] => def
)
**************************************************************************************************************************************************************************************/
<?php
$subject = "abcdef";
$pattern = '/def/';
preg_match($pattern, $subject, $matches, PREG_OFFSET_CAPTURE);
print_r($matches);
/********返回
Array
(
[0] => Array
(
[0] => def
[1] => 3
)
)
**************************************************************************************************************************************************************************************/
<?php
$subject = "abcdef";
$pattern = '/def/';
preg_match($pattern, $subject, $matches, PREG_OFFSET_CAPTURE,4);//从下标为4的字符开始搜索
print_r($matches);
/********返回
Array
(
)
**************************************************************************************************************************************************************************************/
preg_match_all
参考preg_match,第四个参数与preg_match有所区别,分为三个选项:PREG_PATTERN_ORDER,PREG_SET_ORDER,PREG_OFFSET_CAPTURE.
PREG_PATTERN为默认的,匹配的结果
$matchs
是多维数组,$matchs[0]
存放完整模式的集合,$matchs[1]
子模式的集合。PREG_SET_ORDER为默认的,匹配的结果
$matchs
是多维数组,$matchs[0][]
存放匹配的第一个完整模式,$matchs[0][1]
存放匹配的第一个子模式,依次类推。PREG_OFFSET_CAPTURE和preg_match的第四个参数差不多。可以返回对应匹配到的位置。
preg_replace
mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )
第二个参数可以传递为数组。
第四个参数为限制匹配次数,默认-1,代表无限次。
第五个参数为完成替换的次数。可以进行输出查看。
<?php
$string = 'April 15, 2003****April 15, 2003'."\n";
$pattern = '/(\w+) (\d+), (\d+)/i';
$replacement = '${1}1,$3';
echo preg_replace($pattern, $replacement, $string, -1 ,$count);
echo $count;
/********返回
April1,2003****April1,2003
2
**************************************************************************************************************************************************************************************/
preg_replace_callback
mixed preg_replace_callback ( mixed $pattern , callable $callback , mixed $subject [, int $limit = -1 [, int &$count ]] )
这个函数的行为除了 可以指定一个 callback 替代 replacement 进行替换 字符串的计算,其他方面等同于 preg_replace()。
php版本 说明 5.3.0 可以使用匿名函数。 5.4.0 $this 可用于匿名函数。
preg_filter
等同于preg_replace过滤掉了没有匹配成功的字符串。
<?php
$subject = array('1', 'a', '2', 'b', '3', 'A', 'B', '4');
$pattern = array('/\d/', '/[a-z]/', '/[1a]/');
$replace = array('A:$0', 'B:$0', 'C:$0');
//运行流程,通过第一个pattern,匹配并且替换得到结果1,然后将结果1通过第二个pattern进行匹配替换,以此类推···
print_r(preg_filter($pattern, $replace, $subject));
print_r(preg_replace($pattern, $replace, $subject));
/********返回
Array
(
[0] => A:C:1
[1] => B:C:a
[2] => A:2
[3] => B:b
[4] => A:3
[7] => A:4
)
Array
(
[0] => A:C:1
[1] => B:C:a
[2] => A:2
[3] => B:b
[4] => A:3
[5] => A
[6] => B
[7] => A:4
)
**************************************************************************************************************************************************************************************/
preg_split
Split the given string by a regular expression.
array preg_split ( string $pattern , string $subject [, int $limit = -1 [, int $flags = 0 ]] )
flags
PREG_SPLIT_NO_EMPTY
If this flag is set, only non-empty pieces will be returned by preg_split().
PREG_SPLIT_DELIM_CAPTURE
If this flag is set, parenthesized expression in the delimiter pattern will be captured and returned as well.
PREG_SPLIT_OFFSET_CAPTURE
If this flag is set, for every occurring match the appendant string offset will also be returned. Note that this changes the return value in an array where every element is an array consisting of the matched string at offset 0 and its string offset into
subject
at offset 1.
正则表达式
正则引擎
主流正则引擎分为三种:一、DFA,二、传统型NFA,三、POSIX NFA。
DFA
DFA:确定性有穷自动机,以原字符串为基准,按字符依次测试表达式。
NFA:非确定性有穷自动机,以表达式为基准,不断测试原字符串。
DFA引擎则搜索更快一些!但是NFA以表达式为主导,反而更容易操纵,因此一般程序员更偏爱NFA引擎!
DFA引擎的程序:awk,egrep,flex,lex,MySQL,Procmail等;
传统型NFA引擎的程序:GNU Emacs,Java,ergp,less,more,.NET语言,PCRE library,Perl,PHP,Python,Ruby,sed,vi;
POSIX NFA引擎的程序:mawk,Mortice Kern Systems’ utilities,GNU Emacs(使用时可以明确指定);
DFA/NFA混合的引擎:GNU awk,GNU grep/egrep,Tcl。
php中的正则
php中有两套正则:POSIX,PCRE。其中POSIX在php 5.3后就不再推荐,若使用会暴deprecated级别错误。
元字符
元字符 | 描述 |
---|---|
^ | 匹配输入字符串的开始位置。如果设置了RegExp对象的Multiline属性,^也匹配“\n”或“\r”之后的位置。 |
$ | 匹配输入字符串的结束位置。如果设置了RegExp对象的Multiline属性,$也匹配“\n”或“\r”之前的位置。 |
? | 匹配前面的子表达式零次或一次。例如,“do(es)?”可以匹配“do”或“does”中的“do”。?等价于{0,1}。 |
.点 | 匹配除“\r\n”之外的任何单个字符。要匹配包括“\r\n”在内的任何字符,请使用像“[\s\S]”的模式。 |
(?:pattern) | 非获取匹配,匹配pattern但不获取匹配结果,不进行存储供以后使用。这在使用或字符“(|)”来组合一个模式的各个部分时很有用。例如“industr(?:y|ies)”就是一个比“industry|industries”更简略的表达式。 |
(?=pattern) | 非获取匹配,正向肯定预查,在任何匹配pattern的字符串开始处匹配查找字符串,该匹配不需要获取供以后使用。例如,“Windows(?=95|98|NT|2000)”能匹配“Windows2000”中的“Windows”,但不能匹配“Windows3.1”中的“Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。 |
(?!pattern) | 非获取匹配,正向否定预查,在任何不匹配pattern的字符串开始处匹配查找字符串,该匹配不需要获取供以后使用。例如“Windows(?!95|98|NT|2000)”能匹配“Windows3.1”中的“Windows”,但不能匹配“Windows2000”中的“Windows”。 |
(?<=pattern) | 非获取匹配,反向肯定预查,与正向肯定预查类似,只是方向相反。例如,“(?<=95|98|NT|2000)Windows”能匹配“2000Windows”中的“Windows”,但不能匹配“3.1Windows”中的“Windows”。 |
(? | 非获取匹配,反向否定预查,与正向否定预查类似,只是方向相反。例如“(?<!95|98|NT|2000)Windows”能匹配“3.1Windows”中的“Windows”,但不能匹配“2000Windows”中的“Windows”。这个地方不正确,有问题此处用或任意一项都不能超过2位,如“(?<!95|98|NT|20)Windows正确,“(?<!95|980|NT|20)Windows 报错,若是单独使用则无限制,如(?<!2000)Windows 正确匹配 |
\b | 匹配一个单词边界,也就是指单词和空格间的位置(即正则表达式的“匹配”有两种概念,一种是匹配字符,一种是匹配位置,这里的\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”字符。 |
\f | 匹配一个换页符。等价于\x0c和\cL。 |
\n | 匹配一个换行符。等价于\x0a和\cJ。 |
\r | 匹配一个回车符。等价于\x0d和\cM。 |
\s | 匹配任何不可见字符,包括空格、制表符、换页符等等。等价于[ \f\n\r\t\v]。 |
\S | 匹配任何可见字符。等价于[^ \f\n\r\t\v] 。 |
\t | 匹配一个制表符。等价于\x09和\cI。 |
\v | 匹配一个垂直制表符。等价于\x0b和\cK。 |
\w | 匹配包括下划线的任何单词字符。类似但不等价于“[A-Za-z0-9_]”,这里的”单词”字符使用Unicode字符集。 |
\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-7),且m和l均为八进制数字(0-7),则匹配八进制转义值nml。 |
\un | 匹配n,其中n是一个用四个十六进制数字表示的Unicode字符。例如,\u00A9匹配版权符号(©)。 |
\p{P} | 小写 p 是 property 的意思,表示 Unicode 属性,用于 Unicode 正表达式的前缀。中括号内的“P”表示Unicode 字符集七个字符属性之一:标点字符。其他六个属性:L:字母;M:标记符号(一般不会单独出现);Z:分隔符(比如空格、换行等);S:符号(比如数学符号、货币符号等);N:数字(比如阿拉伯数字、罗马数字等);C:其他字符。*注:此语法部分语言不支持,例:javascript。 |
< > | 匹配词(word)的开始(<)和结束(>)。例如正则表达式能够匹配字符串”for the wise”中的”the”,但是不能匹配字符串”otherwise”中的”the”。注意:这个元字符不是所有的软件都支持的。 |
( ) | 将( 和 ) 之间的表达式定义为“组”(group),并且将匹配这个表达式的字符保存到一个临时区域(一个正则表达式中最多可以保存9个),它们可以用 \1 到\9 的符号来引用。 |
| | 将两个匹配条件进行逻辑“或”(Or)运算。例如正则表达式(him|her) 匹配”it belongs to him”和”it belongs to her”,但是不能匹配”it belongs to them.”。注意:这个元字符不是所有的软件都支持的。 |
+ | 匹配1或多个正好在它之前的那个字符。例如正则表达式9+匹配9、99、999等。注意:这个元字符不是所有的软件都支持的。 |
? | 匹配0或1个正好在它之前的那个字符。注意:这个元字符不是所有的软件都支持的。 |
php正则积累
\Q和\E之间的元字符会被当作普通字符。
匹配分支,从左向右匹配,如果满足一个则不再考虑其他分支。所以这种写法错误:\d{5}|\d{5}-\d{4}
//反向引用'\1'代表分组引用匹配的文本,而不是表达式。
<?php
var_dump(preg_match("/(\"|').*?(\"|')/","\"this is a 'string'\"",$res1));
var_dump($res1);
$str="\"this is a 'string'\"";
var_dump(preg_match("/(\"|').*?(\"|')/",$str,$res2));
var_dump($res2);
$str="\"this is a 'string'\"";
var_dump(preg_match("/(\"|').*?\\1/","\"this is a 'string'\"",$res3));
var_dump($res3);
$str="\"this is a 'string'\"";
var_dump(preg_match("/(?P<quote>\"|').*?(?P=quote)/","\"this is a 'string'\"",$res4));
var_dump($res4);
/*******************输出**************************
int(1)
array(3) {
[0] =>
string(12) ""this is a '"
[1] =>
string(1) """
[2] =>
string(1) "'"
}
int(1)
array(3) {
[0] =>
string(12) ""this is a '"
[1] =>
string(1) """
[2] =>
string(1) "'"
}
int(1)
array(2) {
[0] =>
string(20) ""this is a 'string'""
[1] =>
string(1) """
}
int(1)
array(3) {
[0] =>
string(20) ""this is a 'string'""
'quote' =>
string(1) """
[1] =>
string(1) """
}
***************************************/
顺序肯定环视
preg_match_all('/\b\w+(?=ing\b)/','i am singing while you are dancing',$res);
var_dump($res);
/**********************输出
array(1) {
[0] =>
array(2) {
[0] =>
string(4) "sing"
[1] =>
string(4) "danc"
}
}
*****************************/
逆序肯定环视
preg_match_all('/(?<=\bre)\w+\b/','reading a book',$res);
var_dump($res);
/**********************输出
array(1) {
[0] =>
array(1) {
[0] =>
string(5) "ading"
}
}
*****************************/
preg_match_all('/((?<=\d)\d{3})+\b/','1234567890',$res); //+再一次匹配还是(\d)\d{3},+匹配表达式,\1匹配是文本
var_dump($res);
/**********************输出
array(2) {
[0] =>
array(1) {
[0] =>
string(9) "234567890"
}
[1] =>
array(1) {
[0] =>
string(3) "890"
}
}
*****************************/
//两种断言
preg_match_all('/(?<=\s)\d+(?=\s)/','12345 6789 0 ',$res);
var_dump($res);
/**********************输出
array(1) {
[0] =>
array(2) {
[0] =>
string(4) "6789"
[1] =>
string(1) "0"
}
}
*****************************/
顺序否定环视
/************************************************第一个例子************************************************************/
preg_match_all('/\b\w*q[^u]\w*\b/','query queen qim mivq lingten',$res); //注意,这里会匹配出mivq lingten
var_dump($res);
/**********************输出
array(1) {
[0] =>
array(2) {
[0] =>
string(3) "qim"
[1] =>
string(12) "mivq lingten"
}
}
*****************************/
preg_match_all('/\b\w*q(?!u)\w*\b/','query queen qim mivq lingten',$res); //注意,这里不会匹配出mivq lingten,因为环视并不匹配结果
var_dump($res);
/**********************输出
array(1) {
[0] =>
array(2) {
[0] =>
string(3) "qim"
[1] =>
string(4) "mivq"
}
}
*****************************/
/************************************************第二个例子************************************************************/
preg_match_all('/\bc[^au]+t\b/','cat cnt cut cst conduct cubt',$res); //无法满足输出非ca或cu开头,t结尾的单词,顺序否定环视可以
var_dump($res);
/**********************输出
array(1) {
[0] =>
array(2) {
[0] =>
string(3) "cnt"
[1] =>
string(3) "cst"
}
}
*****************************/
preg_match_all('/\bc(?![ua])\w+t\b/','cat cnt cut cst conduct cubt',$res); //
var_dump($res);
/**********************输出
array(1) {
[0] =>
array(3) {
[0] =>
string(3) "cnt"
[1] =>
string(3) "cst"
[2] =>
string(7) "conduct"
}
}
*****************************/
/************************************************第三个例子************************************************************/
preg_match_all('/^(?:(?!cat).)+$/','michaecatl',$res); //匹配文本中不得含有cat
var_dump($res);
/**********************输出
array(1) {
[0] =>
array(0) {
}
}
*****************************/
逆序否定环视
preg_match_all('/(?<![a-z])\d{7}/','BBB1234567aaa2345678_3456789',$res); //
var_dump($res);
/**********************输出
array(1) {
[0] =>
array(2) {
[0] =>
string(7) "1234567"
[1] =>
string(7) "3456789"
}
}
*****************************/
正则中的非关系
<?php
$s=preg_match_all('#<(?!/?p\b)[^>]+>#','ab<p>one</p>cde<div>fgh</div><><img src="1.jpg">',$str);
var_dump($str); //匹配非<p>或者</p>的标签
/******************* 运行结果 **************************
array(1) {
[0] =>
array(3) {
[0] =>
string(5) "<div>"
[1] =>
string(6) "</div>"
[2] =>
string(17) "<img src="1.jpg">"
}
}
********************************************************/
正则表达式中运算符的优先级
运算符 | 描述 |
---|---|
\ | 转义符 |
(), (?:), (?=), [] | 圆括号和方括号 |
*, +, ?, {n}, {n,}, {n,m} | 限定符 |
^, $, \任何元字符、任何字符 | 定位点和序列(即:位置和顺序) |
| | 替换,”或”操作字符具有高于替换运算符的优先级,使得”m|food”匹配”m”或”food”。若要匹配”mood”或”food”,请使用括号创建子表达式,从而产生”(m|f)ood”。 |
正则表达式中的几种模式
1. i ignore
2. m multiline
$s=preg_match_all('#.*reg$#mi','this is reg
Reg
thi is
regexp tuttor , reg',$str);
var_dump($str);
/******************* 运行结果 **************************
array(1) {
[0] =>
array(1) {
[0] =>
string(19) "regexp tuttor , reg"
}
}
********************************************************/
//但是如果把m模式去掉,结果是一样的,说明$指明的是最后一行。
$s=preg_match_all('#^t.*#mi','this is reg
Reg
thi is
regexp tuttor , reg',$str);
var_dump($str);
/******************* 运行结果 **************************
array(1) {
[0] =>
array(2) {
[0] =>
string(12) "this is reg"
[1] =>
string(8) "thi is "
}
}
//去掉m只会匹配第一行,注意理解多行和跨行的区别,这边是多行 multi.
********************************************************/
3. s 点号通配模式
$s=preg_match_all('#^t.*#s','this is reg
Reg
thi is
regexp tuttor , reg',$str);
var_dump($str);
/******************* 运行结果 **************************
array(1) {
[0] =>
array(1) {
[0] =>
string(46) "this is reg
Reg
thi is
regexp tuttor , reg"
}
}
********************************************************/
//使得点号可以匹配换行符号
4. U 懒惰模式
5. D 结尾限制
功力不够,未能理解。
6. UTF-8转义表达
$s=preg_match_all('#^[\x{4e00}-\x{9fa5}]+$#u',"说啥呢",$str);
var_dump($str);
//如果说啥呢三个字是utf-8编码即可匹配出,如果是gbk编码,则匹配不出。