程序员的知识教程库

网站首页 > 教程分享 正文

PHP 正则表达式perl函数(php正则表达式实例)

henian88 2024-10-10 05:51:39 教程分享 2 ℃ 0 评论

preg_match() 执行一个正则表达式匹配

该函数只作一次匹配,最终返回0或1的匹配结果数

int preg_match ( string $pattern , string $subject [, array &$matches ] )

<?php
$pattern='/(https?|ftps?|http?):\/\/(www)\.([^\.\/]+)\.(com|net|org)(\/[\w-\.\/\?\%\&\=]*)?/i'; //正则表达式
$subject="网址为http://www.xxxxxx.com/index.php网站搜索"; //被搜索字符串

if(preg_match($pattern, $subject, $matches)) { //使用preg_match()函数进行匹配
    echo "搜索到的URL为:".$matches[0]."<br>"; //数组中第一个元素保存全部匹配结果
    echo "URL中的协议为:".$matches[1]."<br>"; //数组中第二个元素保存第一个子表达式
    echo "URL中的主机为:".$matches[2]."<br>"; //数组中第三个元素保存第二个子表达式
    echo "URL中的域名为:".$matches[3]."<br>"; //数组中第四个元素保存第三个子表达式
    echo "URL中的顶域为:".$matches[4]."<br>"; //数组中第五个元素保存第四个子表达式
    echo "URL中的文件为:".$matches[5]."<br>"; //数组中第六个元素保存第五 个子表达式
} else {
    echo "搜索失败!"; //如果和正则表达式没有匹配成功则输出此条语句
}
?>

preg_match_all() 执行一个全局正则表达式匹配, 返回完整匹配次数(可能是0), 或者如果发生错误返回FALSE。

int preg_match_all ( string $pattern , string $subject [, array &$matches [, int $flags = PREG_PATTERN_ORDER ]] )

PREG_PATTERN_ORDER 为默认值, 结果排序为$matches[0]保存完整模式的所有匹配, $matches[1] 保存第一个子组的所有匹配, 以此类推。

PREG_SET_ORDER 结果排序为$matches[0]包含第一次匹配得到的所有匹配(包含子组), $matches[1]是包含第二次匹配到的

所有匹配(包含子组)的数组, 以此类推。

<?php
$pattern='/(https?|ftps?):\/\/(www|mail)\.([^\.\/]+)\.(com|net|org)(\/[\w-\.\/\?\%\&\=]*)?/i';
//声明一个包含多个URL链接地址的多行文字
$subject="网址为http://mail.xxxxxx.net/index.php电子邮箱,
网址为http://www.baidu.com/index.php搜索文件,
网址为http://www.google.com/index.php搜索文件。";
$i=1; //定义一个计数器,用来统计搜索到的结果数
if(preg_match_all($pattern, $subject, $matches, PREG_SET_ORDER)) { //搜索全部的结果
    foreach($matches as $urls) //循环遍历二维数组$matches
    {
        echo "搜索到第".$i."个URL为:".$urls[0]."<br>";
        echo "第".$i."个URL中的协议为:".$urls[1]."<br>";
        echo "第".$i."个URL中的主机为:".$urls[2]."<br>";
        echo "第".$i."个URL中的域名为:".$urls[3]."<br>";
        echo "第".$i."个URL中的顶域为:".$urls[4]."<br>";
        echo "第".$i."个URL中的文件为:".$urls[5]."<br>";
        $i++; //计数器累加
    }
} else {
    echo "搜索失败!";
}
?>

输出:搜索到第1个URL为:http://mail.xxxxxx.net/index.php

第1个URL中的协议为:http

第1个URL中的主机为:mail

第1个URL中的域名为:xxxxxx

第1个URL中的顶域为:net

第1个URL中的文件为:/index.php

搜索到第2个URL为:http://www.baidu.com/index.php

第2个URL中的协议为:http

第2个URL中的主机为:www

第2个URL中的域名为:baidu

第2个URL中的顶域为:com

第2个URL中的文件为:/index.php

搜索到第3个URL为:http://www.google.com/index.php

第3个URL中的协议为:http

第3个URL中的主机为:www

第3个URL中的域名为:google

第3个URL中的顶域为:com

第3个URL中的文件为:/index.php


preg_grep — 返回匹配模式的数组条目

array preg_grep ( string $pattern , array $input )

如果数组带关联数组则保留键名

如果数组不带键名,则重新赋予键名

<?php
$array=array("Linux RedHat7.0", "Apache2.3.2", "MySQL5.7.31", "PHP5.6.6", "LNMP", "130");
//返回数组中以字母开始和以数字结束,并且没有空格的单元,赋给变量$version
$version=preg_grep("/^[a-zA-Z]+(\d|\.)+$/", $array);
print_r($version); //输出:Array ( [1] => Apache2.3.2 [2] => MySQL5.7.31 [3] => PHP5.6.6 )
?>

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

注意:"\\1"等同于 "\${1}"的形式;

\${1}不能在单引号模式下使用, '\${1}'则会原样输出${1}

如果是两位数的逆向引用, 则采用"\${12}";

如果是一个数后面还有数子, 则采用"\${1}2",

preg_replace()不能识别两位数字的子模式:"\\12";

使用preg_replace()函数时, 最常见的形式就是可以包含反向引用, 即使用"\\n"的形式依次引用正则表达式的模式单元。每个此种引用将被替换

为与第n个被捕获的括号内的子模式所匹配的文本,n可以从0到99,其中\\0指的是被整个模式所匹配的文本,对左圆括号从左到右计数(从1开始)以取得

子模式的数目。

对替换模式在一个逆向引用后面紧接着一个数字时(即紧接着在一个匹配的模式后面的数字),不能使用熟悉的\\1符号来表示逆向引用。

举例说明\\11,将会使preg_replace()搞不清楚是想要第一个\\1的逆向引用后面跟着一个数字1还是一个\\11的逆向引用。

本例中的解决方法是使用\${1}1,这将会形成一个隔离的$1逆向引用,而另一个1只是单纯的文字。

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

第四个参数值默认值为-1, 则所有的匹配项都会被替换

<?php
$pattern="/<[\/\!]* ?[^<>]*?>/is"; //可以匹配所有HTML标记的开始和结束的正则表达式
//声明一个带有多个HTML标记的文本
$text="这个文本中有<b>粗体</b>和<u>带有下划线</u>以及<i>斜体</i>还有<font color='red' size='7'>带有颜色和字体大小</font>的标记";
echo preg_replace($pattern, "", $text); //将所有HTML标记替换为空,即删除所有HTML标记
echo "<br>"; //输出换行
echo preg_replace($pattern, "", $text, 2); //通过第四个参数传入数字2,替换前两个HTML标记
?>

"\\1" 双斜线

<?php
$pattern="/(\d{2})\/(\d{2})\/(\d{4})/"; //日期格式的正则表达式
$text="今年春节放假日期为01/25/2009到02/02/2009共7天。"; //带有两个日期格式的字符串
echo preg_replace($pattern, "\\3-\\1-\\2", $text); //将日期替换为以"-"分隔的格式
echo preg_replace($pattern, "\${3}-\${1}-\${2}",$text); //将"\\1"改为"\${1}"的形式
?>

'\1' 单斜线

<?php
$patterns = array ('/(19|20)(\d{2})-(\d{1,2})-(\d{1,2})/',
'/^\s*{(\w+)}\s*=/');
$replace = array ('\3/\4/\1\2', '$\1 ='); // 在子模式中,定界符"/"不需要去转义
echo preg_replace($patterns, $replace, '{startDate} = 1999-5-27');
?>

输出:$startDate = 5/27/1999

实例: 将HTML标记转换为小写:

<?php
$pattern="/(<\/?)(\w+)([^>]*>)/e"; //可以匹配所有HTML标记的开始和结束的正则表达式
//声明一个带有多个HTML标记的文本
$text="这个文本中有<b>粗体</b>和<u>带有下划线</u>以及<i>斜体</i>还有<font color='red' size='7'>带有颜色和字体大小</font>的标记";
$text1='这个文本中有<b>粗体</b>和<u>带有下划线</u>以及<i>斜体</i>还有<font color="red" size="7">带有颜色和字体大小</font>的标记';
echo preg_replace($pattern, "'\\1'.strtoupper('\\2').'\\3'", $text); //将所有HTML的小写标记替换为大写, 正确的语法
echo "<br />";
echo preg_replace($pattern, "'\1'.strtoupper('\2').'\3'", $text); //与上面的结果是不同的,清除了HTML标签
echo "<br />";
echo preg_replace($pattern, '"\1".strtoupper("\2").stripslashes("\3")', $text); //将所有HTML的小写标记替换为大写, 正确的语法
echo "<br />";
echo preg_replace($pattern, '"\\1".strtoupper("\\2")."\\3"', $text); // 自动添加了反斜线 <FONT color=\'red\' size=\'7\'>
echo "<br />";
echo preg_replace($pattern, "'\\1'.strtoupper('\\2').'\\3'", $text1);// 自动添加了反斜线 <FONT color=\'red\' size=\'7\'>
?>

注意:在双引号包括的单引号内部仍然使用\\1(两个反斜线)去捕获子模式;而在单引号包括的双引号内部可以\1(推荐使用)或\\1去捕获子模式;

所以应该考虑外层的引号决定反斜线的数目

为何要使用stripslashes()函数,因为在替换的过程中<font color='red' size='7'>自动添加转义字符,替换的结果为<FONT color=\'red\' size=\'7\'>

而参数$replacement与参数$subject引号未对应(外层与内层的引号未对应), 所以要用stripslashes()函数清除转义字符

去除含有中文的字符串

<?php
$string = "xxxxxx网www.xxxxxx.com";
$str = preg_replace('/([\x80-\xff]*)/i','',$string); //去掉中文汉字
echo $str;
?>

经过严格测试:GB2312和utf-8均可以使用

去除特定的a链接

<?php
$str = '<a class="autolink" title="第7章 文件基础" href="http://192.168.0.52/mod/resource/view.php?id=391">第7章 文件基础</a>';
echo preg_replace('/<a class="autolink" [^>]*>(.*?)<\/a>/is', "$1", $str);
?>

preg_split() 通过一个正则表达式分隔字符串

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

pattern:用于搜索的模式, 字符串形式。

subject:输入字符串

第三个参数:limit 如果指定, 将限制分隔得到的子串最多只有limit个, 返回的最后一个 子串将包含所有剩余部分。

limit值为-1, 0或null时都代表"不限制", 作为php的标准, 你可以使用null跳过对flags的设置。

第四个参数:flags 可以是任何下面标记的组合(以位或运算 | 组合):

PREG_SPLIT_NO_EMPTY(1)如果这个标记被设置, preg_split() 将进返回分隔后的非空部分

PREG_SPLIT_DELIM_CAPTURE(0)如果这个标记设置了,用于分隔的模式中的括号表达式内容将被捕获并返回。PREG_SPLIT_DELIM_CAPTURE为默认值(0)

PREG_SPLIT_OFFSET_CAPTURE(4)如果这个标记被设置,对于每一个出现的匹配返回时将会附加字符串偏移量.

注意:这将会改变返回数组中的每一个元素, 使其每个元素成为一个由第0个元素为分隔后的子串,第1个元素为该子串在subject中的偏移量组成的数组。

<?php
//按任意数量的空格和逗号分隔字符串,其中包含" ", \r, \t, \n and \f
$keywords = preg_split ("/[\s,]+/", "hypertext language, programming");
print_r($keywords); //分割后输出Array ( [0] => hypertext [1] => language [2] => programming )

//将字符串分割成字符
$chars = preg_split('//', "lamp", -1, PREG_SPLIT_NO_EMPTY);
print_r($chars); //分割后输出Array ( [0] => l [1] => a [2] => m [3] => p )

//将字符串分割为匹配项及其偏移量
$chars = preg_split('/ /','hypertext language programming', -1, PREG_SPLIT_OFFSET_CAPTURE);
print_r($chars);

/* 分割后输出Array ( [0] => Array ( [0] => hypertext [1] => 0 )
* [1] => Array ( [0] => language [1] => 10 )
* [2] => Array ( [0] => programming [1] => 19 ) ) */
?>

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表