php正規表現貪欲モードと非貪欲について
仕事では、正規表現を使って、私たちが望んでいるデータに一致させ、一致したデータを必要とするデータに置き換えることもよくあります.このすべては、難しいようですが、正規表現を上手に使うことができれば、これらは料理ではありません.
一、貪欲と非貪欲
貪欲モード:このように考えることができて、全体の表現式のマッチングが成功する前提の下で、できるだけ多くのマッチング、つまりいわゆる“貪欲”で、通俗的に言えば、欲しいものを見て、いくらでも拾って、二度と欲しくない限り.
非貪欲モード:このように考えることができて、全体の表現式のマッチングが成功する前提の下で、できるだけ少ないマッチング、つまりいわゆる“非貪欲”で、通俗的に言えば、1つの欲しいものを見つけて拾えばいいので、まだ拾っていないものがあるかどうかは気にしないでください.
貪欲とは何か、例えば文字列の中からソーセージ月餅食べ物を食べるということです.もともとソーセージしか食べられませんが、貪欲で、最初のから最後のの中の2つの食べ物を取り出して、もっと食べたいと思っています.貪欲ではありません.つまり、あなたは貪欲ではありません.ソーセージだけを食べます.
正則の中でどのように貪欲なのかを見てみましょう.
このようにして出力される結果は、
どうやって貪欲を制限しますか?
マッチング回数の特殊記号を修飾した後に「?をクリックします.
このようにして出力される結果は、
PHPではモード修飾子によっても実現でき、大文字の「U」:
このように出力された結果は上と同じです!
二、事前検索
プリサーチは、後で使用するために保存されない非取得マッチングです.
1、事前に「(?=xxxx)」、「(?!xxxx」を検索する
「(?=xxxx」:隙間の右側には、xxxxという部分の式が一致する必要があります.
結果:
これはxpの前のwindowsで、NTと2003の前を取ることはありません.
フォーマット:「(?!xxxx)」は、隙間の右側にあり、xxxxという表現に一致しない必要があります.
結果:
ここから,プリサーチは後で使用するための記憶を行わないことが分かる.会議に参加したストレージの比較.
結果:
2、逆方向の事前検索
"(?<=xxxxx)","(?「(?<=xxxx)」:隙間にある「左側」はxxxx部分にマッチします.
前の4つの数字と後の4つの数字を除いた中間の8つの数字「(?
結果:
@次の例は主に3つの関数について話しています.
preg_replace();
preg_match_all();preg_match()の基本的な使い方.興味があれば見てみましょう.
例1:
交換が必要なものをparrerns配列に入れ、交換したデータを
$stringは文字列であり、$patternsをインデックスベースの配列として定義します.
関数の説明:preg_replace();mixedpreg_replace ( mixed
検索
以上の例が出力されます.
上記の例では、置き換える必要がある値をインデックス配列の形で表現して、一つ一つ置き換えることができますが、便利ではないでしょうか.
例2:
文字列の中の日付を現在の日付や必要なものに変える必要があります
以上の例が出力されます.
文字列の中の日付が今日の日付に変更されました.
例3:
正規表現は、下線が最初に表示される前の内容とどのように一致しますか?
関数の説明:preg_match_all();intpreg_match_all (string
最初の一致が見つかった後、サブシーケンスは最後の一致位置から検索を継続する.
以上の例が出力されます.
上の配列は次のように印刷されます.
例4:
関数の説明:preg_match()探索
preg_match()は
以上の例が出力されます.
文字列内の時間マッチングに成功しました.
例5:
一致文字列のurl
以上の例が出力されます.
@実際には、URLに一致する機能を完了するために関数をカプセル化することもできます.
以上の例が出力されます.
一、貪欲と非貪欲
貪欲モード:このように考えることができて、全体の表現式のマッチングが成功する前提の下で、できるだけ多くのマッチング、つまりいわゆる“貪欲”で、通俗的に言えば、欲しいものを見て、いくらでも拾って、二度と欲しくない限り.
非貪欲モード:このように考えることができて、全体の表現式のマッチングが成功する前提の下で、できるだけ少ないマッチング、つまりいわゆる“非貪欲”で、通俗的に言えば、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()探索
subject
とpattern
で与える正規表現との一致.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