php正規表現貪欲モードと非貪欲について

9503 ワード

仕事では、正規表現を使って、私たちが望んでいるデータに一致させ、一致したデータを必要とするデータに置き換えることもよくあります.このすべては、難しいようですが、正規表現を上手に使うことができれば、これらは料理ではありません.
一、貪欲と非貪欲
貪欲モード:このように考えることができて、全体の表現式のマッチングが成功する前提の下で、できるだけ多くのマッチング、つまりいわゆる“貪欲”で、通俗的に言えば、欲しいものを見て、いくらでも拾って、二度と欲しくない限り.
非貪欲モード:このように考えることができて、全体の表現式のマッチングが成功する前提の下で、できるだけ少ないマッチング、つまりいわゆる“非貪欲”で、通俗的に言えば、1つの欲しいものを見つけて拾えばいいので、まだ拾っていないものがあるかどうかは気にしないでください.
貪欲とは何か、例えば文字列の中からソーセージ月餅食べ物を食べるということです.もともとソーセージしか食べられませんが、貪欲で、最初のから最後のの中の2つの食べ物を取り出して、もっと食べたいと思っています.貪欲ではありません.つまり、あなたは貪欲ではありません.ソーセージだけを食べます.
正則の中でどのように貪欲なのかを見てみましょう.
<?php
$str = '<td>  </td><td>  </td>';
preg_match('/<td>(.*)<\/td>/',$str,$rs);
print_r($rs);
?>

このようにして出力される結果は、
Array ( [0] =>      [1] =>      ) 

どうやって貪欲を制限しますか?
マッチング回数の特殊記号を修飾した後に「?をクリックします.
<?php
$str = '<td>  </td><td>  </td>';
preg_match('/<td>(.*?)<\/td>/',$str,$rs);
print_r($rs);
?>

このようにして出力される結果は、
Array ( [0] =>    [1] =>    ) 

PHPではモード修飾子によっても実現でき、大文字の「U」:
<?php
$str = '<td>  </td><td>  </td>';
preg_match('/<td>(.*)<\/td>/U',$str,$rs);
print_r($rs);
?>

このように出力された結果は上と同じです!
二、事前検索
プリサーチは、後で使用するために保存されない非取得マッチングです.
1、事前に「(?=xxxx)」、「(?!xxxx」を検索する
「(?=xxxx」:隙間の右側には、xxxxという部分の式が一致する必要があります.
<?php
$str = 'windows NT windows 2003 windows xp';
preg_match('/windows (?=xp)/',$str,$res);
print_r($res);
?>

結果:
Array 
( 
    [0] => windows 
)

これはxpの前のwindowsで、NTと2003の前を取ることはありません.
フォーマット:「(?!xxxx)」は、隙間の右側にあり、xxxxという表現に一致しない必要があります.
<?php
$str = 'windows NT windows 2003 windows xp';
preg_match_all('/windows (?!xp)/',$str,$res);
print_r($res);
?>

結果:
Array 
( 
    [0] => Array 
        ( 
            [0] => windows       nt    
            [1] => windows       2003    
        )
)

ここから,プリサーチは後で使用するための記憶を行わないことが分かる.会議に参加したストレージの比較.
<?php
$str = 'windows NT windows 2003 windows xp';
preg_match_all('/windows ([^xp])/',$str,$res);
print_r($res);
?>

結果:
Array 
( 
    [0] => Array                 
   ( 
            [0] => windows N   
            [1] => windows 2 
        )
    [1] => Array                  ,      。 
        ( 
            [0] => N 
            [1] => 2 
        )
)

2、逆方向の事前検索
"(?<=xxxxx)","(?「(?<=xxxx)」:隙間にある「左側」はxxxx部分にマッチします.
<?php
$str = '1234567890123456';
preg_match('/(?<=\d{4})\d+(?=\d{4})/',$str,$res);
print_r($res);
?>
結果:
Array 
( 
    [0] => 56789012 
)

前の4つの数字と後の4つの数字を除いた中間の8つの数字「(?<?php $str = ' 1234567890123456'; preg_match('/(?<! )\d+/',$str,$res); print_r($res); ?>
結果:
Array 
( 
    [0] => 234567890123456 
)

@次の例は主に3つの関数について話しています.
preg_replace();
preg_match_all();preg_match()の基本的な使い方.興味があれば見てみましょう.
例1:
交換が必要なものをparrerns配列に入れ、交換したデータをreplacement :に置きます.
$stringは文字列であり、$patternsをインデックスベースの配列として定義します.
関数の説明:preg_replace();mixedpreg_replace ( mixed $pattern ,mixed $replacement ,mixed $subject [,int $limit = -1 [,int &$count ]] )
検索subjectの一致patternの部分を検索し、replacementに置き換えます.
<?php
date_default_timezone_set("Asia/Shanghai");
$string = 'kemo|addidas|     |haha|2013-12-13 09:00:09|weobo|lail';
$patterns = array();
$patterns[0] = '/2013-12-13 09:00:09/';
$patterns[1] = '/weobo/';
$patterns[2] = '/lail/';
$replacements = array();
$replacements[2] = date('Y-m-d H:i:s',time());
$replacements[1] = 'tengx';
$replacements[0] = 'buyao';
echo preg_replace($patterns, $replacements, $string);
?>


以上の例が出力されます.
kemo|addidas|     |haha|2013-12-14 11:40:43|tengx|buyao 

上記の例では、置き換える必要がある値をインデックス配列の形で表現して、一つ一つ置き換えることができますが、便利ではないでしょうか.
例2:
文字列の中の日付を現在の日付や必要なものに変える必要があります
<?php
date_default_timezone_set("Asia/Shanghai");
$string = 'kemo|addidas|     |haha|2013-12-13 09:00:09|weobo|lail'; 
$pattern = '/\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2}/';
$replacement = date('Y-m-d H:i:s',time());
echo preg_replace($pattern, $replacement, $string);
?>

以上の例が出力されます.
kemo|addidas|     |haha|2013-12-14 12:07:55|weobo|lail

文字列の中の日付が今日の日付に変更されました.
例3:
正規表現は、下線が最初に表示される前の内容とどのように一致しますか?
関数の説明:preg_match_all();intpreg_match_all (string $pattern ,string $subject [,array &$matches [,int $flags = PREG_PATTERN_ORDER [,int $offset = 0 ]]] ) subjectのすべての一致patternが正規表現の一致結果を検索し、flagで指定する順序でmatchesに出力.
最初の一致が見つかった後、サブシーケンスは最後の一致位置から検索を継続する.
<?php
date_default_timezone_set("Asia/Shanghai");
$content="                      _   _   _";
preg_match_all('/([^_]*?)_/i',$content, $matches);
if(count($matches[1])>0)
{ 
	echo $matches[1][0];
}
var_dump($matches);
?>

以上の例が出力されます.
                      

上の配列は次のように印刷されます.
array(2) { [0]=> array(3) { [0]=> string(45) "                      _" [1]=> string(7) "   _" [2]=> string(7) "   _" } [1]=> array(3) { [0]=> string(44) "                      " [1]=> string(6) "   " [2]=> string(6) "   " } } 

例4:
関数の説明:preg_match()探索subjectpatternで与える正規表現との一致.
preg_match()はpatternのマッチング回数を返す.preg_match()は、最初の一致後に検索を停止するため、0回(不一致)または1回になります.preg_match_all()はこれとは異なり、最後までsubjectを検索します.エラーが発生した場合match()はFALSEを返します.
<?php  
date_default_timezone_set("Asia/Shanghai");  
$pattern="/\d{4}(\W)\d{2}\\1\d{2}\s+\d{2}(\W)\d{2}\\2\d{2}\s+(?:am|pm)/";   //       
$string="today is 2013/12/14 10:35:28 am...";      //                    

   if(preg_match($pattern, $string, $arr)){
	   echo "      <b>{$pattern} </b>     <b>{$string}</b>     <br>";
	   echo '<pre>';
	   print_r($arr);
	   echo '</pre>';

	
   }else{
   	echo "<font color='red'>     {$pattern}      {$string}     </font>";
   }
?>

以上の例が出力されます.
      /\d{4}(\W)\d{2}\1\d{2}\s+\d{2}(\W)\d{2}\2\d{2}\s+(?:am|pm)/      today is 2013/12/14 10:35:28 am...     

Array
(
    [0] => 2013/12/14 10:35:28 am
    [1] => /
    [2] => :
)

文字列内の時間マッチングに成功しました.
例5:
一致文字列のurl
<?php  
date_default_timezone_set("Asia/Shanghai");  
$str="       https://www.sina.com       ";
$url="/(https?|ftps?):\/\/((www|mail|news)\.([^\.\/]+)\.(com|org|net|cn))/i";
if(preg_match($url, $str, $arr)){
  echo "        URL  <br>";
  echo '<pre>';
  print_r($arr);
  echo '</pre>';
}else{
echo "       URL";
}
?>

以上の例が出力されます.
        URL  

Array
(
    [0] => https://www.sina.com
    [1] => https
    [2] => www.sina.com
    [3] => www
    [4] => sina
    [5] => com
)

@実際には、URLに一致する機能を完了するために関数をカプセル化することもできます.
<?php  
date_default_timezone_set("Asia/Shanghai");  
$str="       https://www.baidu.com       
       http://www.baidu1.com       
       https://mail.baidu2.com       
       https://news.baidu3.com       
       https://www.baidu4.org       
       https://www.baidu5.net       
       ftps://www.baidu6.com       
       ftp://www.google7.com       
       https://www.baidu7.net       ";
function setUrl($str) {
 	$url="/(https?|ftps?):\/\/((www|mail|news)\.([^\.\/]+)\.(com|org|net|cn))/i";
	  preg_match_all($url, $str, $arr,PREG_PATTERN_ORDER );
 	 foreach($arr[0] as $url){
  		$str=str_replace($url, '<a href="'.$url.'">'.$url.'</a>', $str);
	  }

 	 return  $str;
}
echo setUrl($str);
?>

以上の例が出力されます.
       https://www.baidu.com               http://www.baidu1.com               https://mail.baidu2.com               https://news.baidu3.com               https://www.baidu4.org               https://www.baidu5.net               ftps://www.baidu6.com               ftp://www.google7.com               https://www.baidu7.net