|
|
preg_match_all (PHP 3 >= 3.0.9, PHP 4, PHP 5) preg_match_all -- Выполняет глобальный поиск шаблона в строке Описаниеint preg_match_all ( string pattern, string subject, array &matches [, int flags [, int offset]] )
Ищет в строке subject все совпадения с шаблоном
pattern и помещает результат в массив
matches в порядке, определяемом комбинацией флагов
flags.
После нахождения первого соответствия последующие поиски будут осуществляться
не с начала строки, а от конца последнего найденного вхождения.
Дополнительный параметр flags может комбинировать следующие значения
(необходимо понимать, что использование PREG_PATTERN_ORDER одновременно с PREG_SET_ORDER бессмысленно):
- PREG_PATTERN_ORDER
Если этот флаг установлен, результат будет упорядочен следующим образом:
элемент $matches[0] содержит массив полных вхождений шаблона,
элемент $matches[1] содержит массив вхождений первой подмаски, и так далее.
- PREG_SET_ORDER
Если этот флаг установлен, результат будет упорядочен следующим образом:
элемент $matches[0] содержит первый набор вхождений,
элемент $matches[1] содержит второй набор вхождений, и так далее.
В таком случае массив $matches[0] содержит первый набор вхождений, а именно:
элемент $matches[0][0] содержит первое вхождение всего шаблона,
элемент $matches[0][1] содержит первое вхождение первой подмаски, и так далее.
Аналогично массив $matches[1] содержит второй набор вхождений, и так для каждого найденного набора.
- PREG_OFFSET_CAPTURE
В случае, если этот флаг указан, для каждой найденной подстроки будет указана
ее позиция в исходной строке. Необходимо помнить, что этот флаг меняет
формат возвращаемых данных: каждое вхождение возвращается в виде массива,
в нулевом элементе которого содержится найденная подстрока, а в первом - смещение.
Данный флаг доступен в PHP 4.3.0 и выше.
В случае, если никакой флаг не используется, по умолчанию используется
PREG_PATTERN_ORDER.
Поиск осуществляется слева направо, с начала строки. Дополнительный параметр
offset может быть использован для указания альтернативной
начальной позиции для поиска. Дополнительный параметр
offset доступен, начиная с PHP 4.3.3.
Замечание:
Использование параметра offset не эквивалентно
замене сопоставляемой строки выражением substr($subject, $offset)
при вызове функции preg_match_all(), поскольку
шаблон pattern может содержать такие условия как
^, $ или (?<=x).
Вы можете найти соответствующие примеры в описании функции preg_match().
Возвращает количество найденных вхождений шаблона (может быть нулем) либо
FALSE, если во время выполнения возникли какие-либо ошибки.
Пример 1. Получение всех телефонных номеров из текста. |
<?php
preg_match_all("/\(? (\d{3})? \)? (?(1) [\-\s] ) \d{3}-\d{4}/x",
"Call 555-1212 or 1-800-555-1212", $phones);
?>
|
|
Пример 2. Жадный поиск совпадений с HTML-тэгами |
<?php
$html = "<b>bold text</b><a href=howdy.html>click me</a>";
preg_match_all("/(<([\w]+)[^>]*>)(.*)(<\/\\2>)/", $html, $matches);
for ($i=0; $i< count($matches[0]); $i++) {
echo "matched: " . $matches[0][$i] . "\n";
echo "part 1: " . $matches[1][$i] . "\n";
echo "part 2: " . $matches[3][$i] . "\n";
echo "part 3: " . $matches[4][$i] . "\n\n";
}
?>
|
Результат работы примера:
matched: <b>bold text</b>
part 1: <b>
part 2: bold text
part 3: </b>
matched: <a href=howdy.html>click me</a>
part 1: <a href=howdy.html>
part 2: click me
part 3: </a> |
|
Смотрите также preg_match(),
preg_replace(),
и preg_split().
master [[at]] lyrics-bank.com
31-Oct-2007 02:22
I use the following to clean unwanted characters and to have only allowed ones in the string:
<?
preg_match_all ("/[a-zA-Z0-9]*/", $string_in, $string_out_array);
$string_out = "";
for ($i=0; $i < sizeof ($string_out_array[0]); $i++) {
$string_out .= $string_out_array[0][$i];
}
?>
ino
08-Oct-2007 04:32
extract all emails from text
preg_match_all("/[-a-z0-9\._]+@[-a-z0-9\._]+\.[a-z]{2,4}/", file_get_contents('1.txt'), $email);
print_r ($email);
aaron at parecki dot com
30-Jul-2007 05:11
<?php
function ActivateLinks($text) {
$matches = array();
$regex = '/\b([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+[a-zA-Z]{2,4})\b/';
preg_match_all($regex, $text, $matches);
if( count($matches[0]) > 0 ) {
foreach( $matches[0] as $email ) {
$obfuscate = '<a href="mailto:'.$email.'">'.$email.'</a>';
$encrypted = "";
for( $i=0; $i<strlen($obfuscate); $i++ ) {
$ch = ord(substr($obfuscate,$i,1));
$encrypted .= chr(
($ch & 0xF0) +
(($ch & 0x0C) >> 2) +
(($ch & 0x03) << 2)
);
}
$replace = '<script>document.write(swapPairs("'.$encrypted.'"))</script>';
$text = str_replace($email, $replace, $text);
}
}
$text = preg_replace( '/(http|ftp)+(s)?:(\/\/)((\w|\.)+)(\/)?(\S+)?/i',
'<a href="\0">\4</a>', $text );
return $text;
}
?>
mr davin
12-Jul-2007 02:57
<?php
function findinside($start, $end, $string) {
preg_match_all('/' . preg_quote($start, '/') . '([^\.)]+)'. preg_quote($end, '/').'/i', $string, $m);
return $m[1];
}
$start = "mary has";
$end = "lambs.";
$string = "mary has 6 lambs. phil has 13 lambs. mary stole phil's lambs. now mary has all the lambs.";
$out = findinside($start, $end, $string);
print_r ($out);
?>
Han Jun Kwang (me -at- hjk.ikueb.com)
05-Jul-2007 12:38
Here's a simple function to retrieve attribute values of HTML tags:
<?php
function getAttribs($t, $a, $s) {
preg_match_all("/(<".$t." .*?".$a.".*?=.*?\")(.*?)(\".*?>)/", $s, $m);
return $m[2];
}
?>
Where $t is the tag name (e.g. img), $a is the attribute you are looking for (e.g. src) and $s is the HTML string.
phektus at gmail dot com
26-Jun-2007 11:22
If you'd like to include DOUBLE QUOTES on a regular expression for use with preg_match_all, try ESCAPING THRICE, as in: \\\"
For example, the pattern:
'/<table>[\s\w\/<>=\\\"]*<\/table>/'
Should be able to match:
<table>
<row>
<col align="left" valign="top">a</col>
<col align="right" valign="bottom">b</col>
</row>
</table>
.. with all there is under those table tags.
I'm not really sure why this is so, but I tried just the double quote and one or even two escape characters and it won't work. In my frustration I added another one and then it's cool.
chuckie
06-Dec-2006 06:20
This is a function to convert byte offsets into (UTF-8) character offsets (this is reagardless of whether you use /u modifier:
<?php
function mb_preg_match_all($ps_pattern, $ps_subject, &$pa_matches, $pn_flags = PREG_PATTERN_ORDER, $pn_offset = 0, $ps_encoding = NULL) {
if (is_null($ps_encoding))
$ps_encoding = mb_internal_encoding();
$pn_offset = strlen(mb_substr($ps_subject, 0, $pn_offset, $ps_encoding));
$ret = preg_match_all($ps_pattern, $ps_subject, $pa_matches, $pn_flags, $pn_offset);
if ($ret && ($pn_flags & PREG_OFFSET_CAPTURE))
foreach($pa_matches as &$ha_match)
foreach($ha_match as &$ha_match)
$ha_match[1] = mb_strlen(substr($ps_subject, 0, $ha_match[1]), $ps_encoding);
return $ret;
}
?>
sam at NOSPAM dot aigc dot net
03-Nov-2006 01:10
Here's something I made awhile ago to colorize long regular expressions. I can't guarantee it'll work for everything/everyone, but it helps me a lot and might help someone else.
Usage:
<?php echo highlight_regexp("/^[0-9]{2}:[0-9]{2}[apAP]$/"); ?>
<?php
function highlight_regexp($pattern) {
$colors = array(
"/" => "red",
"(" => "green",
")" => "green",
"[" => "blue",
"]" => "blue",
"{" => "orange",
"}" => "orange"
);
$specialchars = array("?","+","*",".","|");
$space = " ";
for ($i = 0; $i < strlen($pattern); $i++) {
unset($spacing);
if ($skip) {
$show = 1;
$skip = 0;
} else
switch ($pattern{$i}) {
case "/":
case "(":
case "[":
case "{":
if ($skip) {
$show = 1;
$skip = 0;
} else {
$tier++;
if ($pattern{$i} == "/")
$tier = 0;
for ($j = 0; $j < $tier; $j++)
$spacing .= $space;
$pattern{$i} == "{" or $return .= "<br>$spacing";
$return .= "<font color=".$colors[$pattern{$i}]."><b>".$pattern{$i}."</b></font>";
if ($pattern{$i} == "(")
$spaceover = "<br>$spacing$space";
else {
if ($pattern{$i} == "[")
$inbrackets = 1;
unset($spaceover);
}
}
$show = 0;
break;
case ")":
case "]":
case "}":
if ($skip) {
$show = 1;
$skip = 0;
} else {
for ($j = 0; $j < $tier; $j++)
$spacing .= $space;
if ($pattern{$i} == ")")
$return .= "<br>$spacing";
elseif ($pattern{$i} == "]")
$inbrackets = 0;
$return .= "<font color=".$colors[$pattern{$i}]."><b>".$pattern{$i}."</b></font>\n";
$spaceover = "<br>$spacing";
$tier--;
}
$show = 0;
break;
default:
$show = 1;
break;
}
if ($show) {
if (!$inbrackets && in_array($pattern{$i},$specialchars)) {
$skipspaceover = 1 ;
$preextra = "<font style='font-weight:bold;color:red'>";
$postextra = "</font>";
$replace = "";
} elseif ($pattern{$i} == " ") {
$preextra = "<i style='font-size:10px'>";
$replace = "(space)";
$postextra = "</i>";
} else
$preextra = $postextra = $replace = $skipspaceover = "";
if ($spaceover && !$skipspaceover) {
$return .= $spaceover;
unset($spaceover);
}
$return .= $preextra.($replace ? $replace : $pattern{$i}).$postextra;
}
}
return $return;
}
?>
mail at SPAMBUSTER at milianw dot de
17-Jul-2006 07:11
I refurnished connum at DONOTSPAMME dot googlemail dot com autoCloseTags function:
<?php
function closetags($html){
preg_match_all("#<([a-z]+)( .*)?(?!/)>#iU",$html,$result);
$openedtags=$result[1];
preg_match_all("#</([a-z]+)>#iU",$html,$result);
$closedtags=$result[1];
$len_opened = count($openedtags);
if(count($closedtags) == $len_opened){
return $html;
}
$openedtags = array_reverse($openedtags);
for($i=0;$i<$len_opened;$i++) {
if (!in_array($openedtags[$i],$closedtags)){
$html .= '</'.$openedtags[$i].'>';
} else {
unset($closedtags[array_search($openedtags[$i],$closedtags)]);
}
}
return $html;
}
?>
phpnet at sinful-music dot com
20-Feb-2006 12:53
Here's some fleecy code to 1. validate RCF2822 conformity of address lists and 2. to extract the address specification (the part commonly known as 'email'). I wouldn't suggest using it for input form email checking, but it might be just what you want for other email applications. I know it can be optimized further, but that part I'll leave up to you nutcrackers. The total length of the resulting Regex is about 30000 bytes. That because it accepts comments. You can remove that by setting $cfws to $fws and it shrinks to about 6000 bytes. Conformity checking is absolutely and strictly referring to RFC2822. Have fun and email me if you have any enhancements!
<?php
function mime_extract_rfc2822_address($string)
{
$crlf = "(?:\r\n)";
$wsp = "[\t ]";
$text = "[\\x01-\\x09\\x0B\\x0C\\x0E-\\x7F]";
$quoted_pair = "(?:\\\\$text)";
$fws = "(?:(?:$wsp*$crlf)?$wsp+)";
$ctext = "[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F" .
"!-'*-[\\]-\\x7F]";
$comment = "(\\((?:$fws?(?:$ctext|$quoted_pair|(?1)))*" .
"$fws?\\))";
$cfws = "(?:(?:$fws?$comment)*(?:(?:$fws?$comment)|$fws))";
$atext = "[!#-'*+\\-\\/0-9=?A-Z\\^-~]";
$atom = "(?:$cfws?$atext+$cfws?)";
$dot_atom_text = "(?:$atext+(?:\\.$atext+)*)";
$dot_atom = "(?:$cfws?$dot_atom_text$cfws?)";
$qtext = "[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F!#-[\\]-\\x7F]";
$qcontent = "(?:$qtext|$quoted_pair)";
$quoted_string = "(?:$cfws?\"(?:$fws?$qcontent)*$fws?\"$cfws?)";
$dtext = "[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F!-Z\\^-\\x7F]";
$dcontent = "(?:$dtext|$quoted_pair)";
$domain_literal = "(?:$cfws?\\[(?:$fws?$dcontent)*$fws?]$cfws?)";
$domain = "(?:$dot_atom|$domain_literal)";
$local_part = "(?:$dot_atom|$quoted_string)";
$addr_spec = "($local_part@$domain)";
$display_name = "(?:(?:$atom|$quoted_string)+)";
$angle_addr = "(?:$cfws?<$addr_spec>$cfws?)";
$name_addr = "(?:$display_name?$angle_addr)";
$mailbox = "(?:$name_addr|$addr_spec)";
$mailbox_list = "(?:(?:(?:(?<=:)|,)$mailbox)+)";
$group = "(?:$display_name:(?:$mailbox_list|$cfws)?;$cfws?)";
$address = "(?:$mailbox|$group)";
$address_list = "(?:(?:^|,)$address)+";
echo(strlen($address_list) . " ");
preg_match_all("/^$address_list$/", $string, $array, PREG_SET_ORDER);
return $array;
};
?>
mnc at u dot nu
02-Feb-2006 10:05
PREG_OFFSET_CAPTURE always seems to provide byte offsets, rather than character position offsets, even when you are using the unicode /u modifier.
egingell at sisna dot com
31-Jan-2006 07:31
Try this for preg_match_all that takes an array of reg expers.
<?
// Emulates preg_match_all() but takes an array instead of a string.
// Returns an array containing all of the matches.
// The return array is an array containing the arrays normally returned by
// preg_match_all() with the optional third parameter supplied.
function preg_search($ary, $subj) {
$matched = array();
if (is_array($ary)) {
foreach ($ary as $v) {
preg_match_all($v, $subj, $matched[]);
}
} else {
preg_match_all($ary, $subj, $matched[]);
}
return $matched;
}
?>
php at projectjj dot com
09-Dec-2005 12:43
If you want to get a string with all the 'normal' characters, this may be better:
$clean = preg_replace('/\W+/', '', $dirty);
\W is the opposite of \w and will match any character that is not a letter or digit or the underscore character, plus it respects the current locale. Use [^0-9a-zA-Z_]+ instead of \W if you need ASCII-only.
b2sing4u at naver dot com
08-Apr-2005 03:42
This function converts all HTML style decimal character code to hexadecimal code.
ex) Hi ο ◊ Dec -> Hi ο ◊ Dec
function d2h($word) {
$n = preg_match_all("/&#(\d+?);/", $word, $match, PREG_PATTERN_ORDER);
for ($j = 0; $j < $n; $j++) {
$word = str_replace($match[0][$j], sprintf("&#x%04X;", $match[1][$j]), $word);
}
return($word);
}
& This function converts all HTML style hexadecimal character code to decimal code.
ex) Hello ο ◊ Hex -> Hello ο ◊ Hex
function h2d($word) {
$n = preg_match_all("/&#x([0-9a-fA-F]+?);/", $word, $match, PREG_PATTERN_ORDER);
for ($j = 0; $j < $n; $j++) {
$word = str_replace($match[0][$j], sprintf("&#%u;", hexdec($match[1][$j])), $word);
}
return($word);
}
fabriceb at gmx dot net
05-Mar-2004 06:55
If you just want to find out how many times a string contains another simple string, don't use preg_match_all like I did before I fould the substr_count function.
Use
<?php
$nrMatches = substr_count ('foobarbar', 'bar');
?>
instead. Hope this helps some other people like me who like to think too complicated :-)
|