细说php2[正则表达式学习笔记]

     《细说php》这本书应该是每个php程序员入门的必读书籍,里面讲的很多知识都很系统和详细,看了正则这部分,并练习了里面的案例,发现自己已经会了很多。。。。


header('Content-type:text/html;charset=utf8;'); /** * 正则表达式的几个函数 * preg_match(, subject) * preg_match_all(pattern, subject, matches) * preg_replace(pattern, replacement, subject) * preg_replace_callback(pattern, callback, subject) * preg_split(pattern, subject) * preg_grep(pattern, input) * */ /** * 正则表达式组成: 定界符+原子+元字符+模式修正符 * */ /** * 原子之通用字符类型 * \d [0-9] * \D [^0-9] * \s [\f\r\n\v] * \S [^\f\r\t\n\v] * \w [0-9a-zA-Z] * \W [^0-9a-zA-Z] */ /*$str = '89898989@qq.cofds'; $pattern = '/^\w+@\w+(\.\w+){2,6}$/i';*/ /*$str = 'ab'; $pattern = '/a\w{1,3}b/';*/ /** * 元字符 * * 0或多次 t > 0 * + 1次或多次 t > 1 * ? 0次或1次 0 <= t <=1 * . 除了换行符以外的任意字符 * | 匹配两个或多个分支 * {n} t = n * {n,} t > n * {n,m} n < t < m * ^ 开头 * $ 结尾 * [] * [^] * () 模式单元, 大原子 */ /** * 后向引用 * */ /*$str = '2008-12-24'; // $pattern = '/^\d{4}\W\d{2}\W\d{2}$/'; $pattern = '/^\d{4}(\W)\d{2}\\1\d{2}$/'; */ $str = 'WinLinuxOs'; $pattern = '/([Win])([Linux])\\2Os/'; if (preg_match($pattern, $str,$matches)) { echo '匹配正确!!!'; } else { echo '匹配失败!!'; } print_r($matches);

 

/**
 * +----------------------------------
 * | 字符串的匹配与查找
 * +----------------------------------
 */
/**
 * +------------------------------------------------------
 * |  preg_match(pattern, subject)
 * +------------------------------------------------------
 */

/*$str = '网址为http://www.erhameng.com/index.php的网址是二哈萌站点';

$pattern = '/(https?|ftps?):\/\/(www).([^\.\/]+)\.(com|cn\net)(\/[\w-\.\/\?\%\&\=]*)?/i';

if (preg_match($pattern, $str, $matchs)) {
  echo '匹配成功!!';
} else {
  echo '匹配失败!!';
}

print_r($matchs);*/

// preg_match_all(pattern, subject, matches)

/*$str = '网址为http://www.erhameng.com/index.php的网址是二哈萌站点
        网址为http://baidu.com/b.php的网址是百度的站点
        网址为http://www.google.com/g.php的网址是谷歌的站点
       ';

$pattern = '/(https?|ftps?):\/\/(www\.)?([^\.\/]+)\.(com|cn|net)(\/[\w-\.\/\?\%\&\=]*)?/i';
$i=1;
if (preg_match_all($pattern, $str, $matchs, PREG_SET_ORDER)) {
  foreach ($matchs as $k => $v) {
  	echo "搜索到第{$i}个网址:" . $v[0] . '<br />';
  	echo "搜索到第{$i}个协议:" . $v[1] . '<br />';
  	echo "搜索到第{$i}个主机:" . $v[2] . '<br />';
  	echo "搜索到第{$i}个域名:" . $v[3] . '<br />';
  	echo "搜索到第{$i}个顶域:" . $v[4] . '<br />';
  	echo "搜索到第{$i}个文件:" . $v[5] . '<br />';
  	$i++;
  }
} else {
  echo '匹配失败!!';
}

print_r($matchs);*/

/**
 * +-----------------------------------------------
 * | 函数 preg_grep(pattern, input)
 * +-----------------------------------------------
 */

/*
$array = array('Linux Redhat9.0', 'Apache2.2.9','Mysql5.5','PHP5.2.6','LAMP',100);

$pattern = '/^[a-zA-Z]+(\d|\.)+$/';

$version = preg_grep($pattern, $array);

print_r($version);
*/

/**
 * +------------------------------------------------------
 * |  preg_replace(pattern, replacement, subject)
 * +------------------------------------------------------
 */
// 

// 1,去除html标签
/*$pattern = '/<[\/\!]*?[^<>]*?>/is';

$str = '这个文本中有<b>粗体</b>和<u>带有下划线</u>以及<i>斜体</i>还有<font color="red">带有颜色的字体</font>的标记';

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

print_r($matchs);*/
//echo preg_replace($pattern, "", $str);

// 2,日期格式的正则
//$pattern = '/(\d{2})\/(\d{2})\/(\d{4})/';

//$str = '今年国庆节10/01/2017到10/07/2017放假共7天';

// echo preg_replace($pattern, "\\3-\\1-\\2", $str);

//echo preg_replace($pattern, "\${3}-\${1}-\${1}", $str);

/*$pattern = '/(<\/?)(\w+)([^>]*>)/e';

$str = '这个文本中有<b>粗体</b>和<u>带有下划线</u>以及<i>斜体</i>还有<font color="red">带有颜色的字体</font>的标记';

echo preg_replace($pattern, "'\\1'.strtoupper('\\2'). '\\3'", $str);*/

/**
 * +------------------------------------------------------
 * |  str_replace(search, replace, subject),可以替换字符串和数组
 * +------------------------------------------------------
 */

/*$str = 'LAMP是目前最流行的web开发平台;<br>
        LAMP是b/s架构的黄金组合;<br>
        LAMP每个成员都是开源的;<br>
        LAMP的开源社区是php.net
        ';
echo str_replace('LAMP', 'Linux apache mysql php', $str, $count) . $count;*/

/**
 * +------------------------------------------------------
 * |  preg_split(pattern, subject)  正则分割
 * +------------------------------------------------------
 */

$words = preg_split('/([\s,]+)/', 'hello newyork city comming here');
print_r($words);

案例:文章发布

artichle.html

 

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>文章发布</title>
</head>
<body>
	<form method="post" action="viewthread.php" target="_blank">
	<h2 align="center">发表文章演示</h2>
    <!-- 下面定义一组选项,使用样式表将其输入在左边 -->
	<div style="width:200; float:left">
		<h5>选项</h5>
		<ul style="list-style:none;margin:0px;padding:0px">
			<li><input type="checkbox" name="parse[]" value="1"> 删除HTML标签</li>
			<li><input type="checkbox" name="parse[]" value="2"> 转换HTML标签为实体</li>
			<li><input type="checkbox" name="parse[]" value="3"> 使用UBB代码</li>
			<li><input type="checkbox" name="parse[]" value="4"> 开启URL识别</li>
			<li title="可用的表情:
							【:), /wx, 微笑】【:@, /fn, 发怒】
							【:kiss, /kill,/sa,示爱】
							【:p, /tx, 偷笑】【:q, /dk, 大哭】">
				<input type="checkbox" name="parse[]" value="5"> 使用表情</li>
			<li><input type="checkbox" name="parse[]" value="6"> 禁用非法关键字</li>
			<li><input type="checkbox" name="parse[]" value="7"> PHP代码设为高亮</li>
			<li><input type="checkbox" name="parse[]" value="8"> 原样显示</li>
			<li><input type="checkbox" name="parse[]" value="9"> 同步换行</li>
		</ul>   
	</div>
    <!-- 下面定义文章的标题和文章内容的输入框,使用样式表取消换行在右边显示 -->
	<div style="width:300; float:left">
		<h5>标题<input type="text" name="subject" size=50></h5>
		<h5>内容<textarea  rows="7" cols="50" name="message"></textarea></h5>
		<input type="submit" name="replysubmit" value="发表帖子">
	</div>
</form>
</body>
</html>

 

viewthread.php

<?php
	/**
		file: viewthread.php
		文章处理脚本
	*/
	//包含脚本文件acticle.class.php,将文章类导入该文件
	require "acticle.class.php";    	
	//创建一个文章对象,在构造方法中传入文章的标题,文章的主体内容以及用户的操作选项
	$article = new Acticle($_POST["subject"], $_POST["message"],$_POST["parse"]);
	//调用文章对象中的获取标题方法,输出文件的标题
	echo $article->getSubject();  
	echo "<hr>";               		//输出一个分隔线,用来分隔文章的标题和主体内容
	echo $article->getMessage();  	//调用文章对象中的获取文章内容的方法,输出文章的主体内容

article.class.php

<?php
	/**
		file:article.class.php
		声明一个文章类,其中有两个成员属性标题和内容,如果需要还可以更多
	*/
	class Acticle {  	
		private $subject;     				   //文章的标题成员属性
		private $message;       			   //文章的主本内容成员属性
		
		//构造方法,通过传入文章标题和文章主体和文章的操作选项数组创建文章对象
		function __construct($subject=" ",$message=" ", $parse=array()) {
			//为文章标题赋初值,将HTML标记转为实体
			$this->subject = $this->html2Text($subject); 
              
			if(!empty($parse)) {         		//如果用户选择了对文章的操作选项则条件成功
				foreach($parse as $value) {		//用户选择了几个文章操作选项则循环几次
					switch($value) {  			//根据用户选择的不同选项,调用不同的内部方法处理
						case 1:      			//如果用户选择“删除HTML标签”选项时条件成立
							$message = $this->delHtmlTags($message); break;
						case 2:      			//如果选择“转换HTML标签为实体”选项时条件成立
							$message = $this->html2Text($message); break;	
						case 3:      			//如果用户选择“使用UBB代码”选项时条件成立
							$message = $this->UBBCode2Html($message); break;
						case 4:      			//如果用户选择“开启URL识别”选项时条件成立
							$message = $this->parseURL($message); break;
						case 5:      			//如果用户选择“使用表情”选项时条件成立
							$message = $this->parseSmilies($message); break;
						case 6:      			//如果用户选择“禁用非法关键字”选项时条件成立
							$message = $this->disableKeyWords($message); break;
						case 7:     			//如果用户选择“PHP代码设为高亮”选项时条件成立
							$message = $this->prasePHPCode($message);	break;
						case 8:      			//如果用户选择“原样显示”选项时条件成立
							$message = $this->prasePer($message); break;
						case 9:      			//如果用户选择“同步换行”选项时条件成立
							$message = $this->nltobr($message); break;
					}
				}	
			}
			//给成员属性$message赋初值
			$this->message = $message;      			
		}
		
		//此私有方法有来删除HTML标记
		private function delHtmlTags($message) {
			//调用字符串处理函数删除HTML标记
			return strip_tags($message);       		
		}

		//此私有方法有来将HTML标记转为HTML实体
		private function html2Text($message) { 		
			//调用字符串处理函数进行操作
			return htmlSpecialChars(stripSlashes($message)); 
		}

		//此私有方法有来解析UBB代码
		private function UBBCode2Html($message) { 
			//声明正则表达式的模板数组
			$pattern = array(							
				'/\[b\]/i', '/\[\/b\]/i', '/\[i\]/i', 	
			    '/\[\/i\]/i', '/\[u\]/i', '/\[\/u\]/i', 
				'/\[font=([^\[\<]+?)\]/i', 
				'/\[color=([#\w]+?)\]/i', 
				'/\[size=(\d+?)\]/i', 
				'/\[size=(\d+(\.\d+)?(px|pt|in|cm|mm|pc|em|ex|%)+?)\]/i',   
				'/\[align=(left|center|right)\]/i', 
				'/\[url=www.([^\["\']+?)\](.+?)\[\/url\]/is', 
				'/\[url=(https?|ftp|gopher|news|telnet){1}:\/\/([^\["\']+?)\](.+?)\[\/url\]/is',
				'/\[email\]\s*([a-z0-9\-_.+]+)@([a-z0-9\-_]+[.][a-z0-9\-_.]+)\s*\[\/email\]/i', 
				'/\[email=([a-z0-9\-_.+]+)@([a-z0-9\-_]+[.][a-z0-9\-_.]+)\](.+?)\[\/email\]/is', 
				'/\[img\](.+?)\[\/img\]/',                      
				'/\[\/color\]/i', '/\[\/size\]/i', '/\[\/font\]/i','/\[\/align\]/'  
			);
    
			//声明正则表达式的替换数组
			$replace = array(						
				'<b>', '</b>', '<i>',    		
				'</i>', '<u>', '</u>', 
				'<font face="\\1">', 
				'<font color="\\1">', 
				'<font size="\\1">', 
				'<font style=\"font-size: \\1\">', 
				'<p align="\\1">', 
				'<a href="http://www.\\1" target="_blank">\\2</a>', 
				'<a href="\\1://\\2" target="_blank">\\3</a>', 
				'<a href="mailto:\\1@\\2">\\1@\\2</a>', 
				'<a href="mailto:\\1@\\2">\\3</a>', 
				'<img src="\\1">', 
				'</font>', '</font>', '</font>', '</p>' 
			);
			//调用正则表达式的替换函数
			return preg_replace($pattern, $replace, $message);  
		}
		
		//此私有方法用来剪切长的URL,并加上链接
		private function cuturl($url) {    			
			$length = 65;
			$url = substr(strtolower($url), 0, 4) == 'www.' ? "http://$url" : $url;
			$urllink = "<a href=\"".$url.'" target="_blank">';
			//如果URL长度大于65则剪切
			if(strlen($url) > $length) {    		
				$url = substr($url, 0, intval($length * 0.5)).' ... '.substr($url, - intval($length * 0.3));
			}
			$urllink .= $url.'</a>';
			return $urllink;
		}
		
		//此私有方法用来解析URL,将其加上链接
		private function parseURL($message) {		
			$urlPattern =   "/(www.|https?:\/\/|ftp:\/\/|news:\/\/|telnet:\/\/){1}([^\[\"']+?)(com|net|org)(\/[\w-\.\/\?\%\&\=]*)?/ei"; 	
			return preg_replace($urlPattern, "\$this->cuturl('\\1\\2\\3\\4')", $message);
		}
		
		//此方法用来解析表情
		private function parseSmilies($message) { 	
			//声明表情的正则表达式模板数组
			$pattern = array(				
					'/:\)|\/wx|微笑/i',    	
					'/:@|\/fn|发怒/i',
					'/:kiss|\/kill|\/sa|示爱/',
					'/:p|\/tx|偷笑/i',
					'/:q|\/dk|大哭/i' 
				);
			
			//声明表情的替换数组
			$replace = array(				
					'<img src="smilies/smile.gif" alt="微笑">',  	
					'<img src="smilies/huffy.gif" alt="发怒">',
					'<img src="smilies/kiss.gif" alt="示爱">',
					'<img src="smilies/titter.gif" alt="偷笑">',
					'<img src="smilies/cry.gif" alt="大哭">'
				);
					
			//调用正则表达式的替换函数		
			return preg_replace($pattern, $replace, $message);	     	
		}
		
		//此方法用来屏蔽文章中的非法关键字
		private function disableKeyWords($message) {	
			$keywords_disable = array("非法关键字一", "非法关键字二", "非法关键字三");
			return str_replace($keywords_disable, "**", $message);
		}

		//此方法用来将PHP代码设置为高亮
		private function prasePHPCode($message) {  	
			$pattern = '/(<\?.*?\?>)/ise';
			$replace = '"<pre style=\"background:#ddd\">".highlight_string("\\1",true)."</pre>"';
			return preg_replace($pattern, $replace, $message);	
		}
			
		//此方法用来将文章原样输出,即加上<pre>标记
		private function prasePer($message) {     		
			return '<pre>'.$message.'</pre>';
		}

		//此私有方法用来将换行符号转为<br>标记
		private function nltobr($message) {  
			//调用字符串处理函数nl2br()
			return nl2br($message);           		
		}	

		//此方法为公有的,返回文章的标题
		public function getSubject() {          		
			return '<h1 align=center>'.$this->subject.'</h1>';
		}

		//此方法为公有的,返回文章的主体内容
		public function getMessage() {         		
			return $this->message;
		}
	}

发布文章测试输入文字:

[b]快快快[/b][size=7][size=8ex][color=#ddd]这行文字[/color][/size][align=center]这是一个p测试[/align]
[url=http://www.baidubaiduab.com]百度[/url]
[url=http://www.fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff.com]这个链接非常长将被拦腰折断[/url]<br>
/wx发怒大哭 <br>我操了他妈的<br>
<?php echo phpinfo();?><br>
this man is \n foo

 

 

posted @ 2017-08-16 01:17  依旧十八岁的夕阳小子  阅读(204)  评论(0编辑  收藏  举报