suche nach in der

preg_match> <preg_last_error
Last updated: Fri, 18 May 2012

view this page in

preg_match_all

(PHP 4, PHP 5)

preg_match_allFührt eine umfassende Suche nach Übereinstimmungen mit regulärem Ausdruck durch

Beschreibung

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

Durchsucht subject nach allen Übereinstimmungen mit dem in pattern angegebenen regulären Ausdruck und legt sie in der durch flags festgelegten Reihenfolge in matches ab.

Nachdem die erste Übereinstimmung gefunden wurde, wird die nachfolgende Suche jeweils am Ende der letzten Übereinstimmung fortgesetzt.

Parameter-Liste

pattern

Der Ausdruck, nach dem gesucht werden soll, als Zeichenkette.

subject

Die zu durchsuchende Zeichenkette.

matches

Ein mehrdimensionales Array mit allen gefundenen Übereinstimmungen, das den flags entsprechend sortiert ist.

flags

Kann eine Kombination folgender Flags sein (beachten Sie, dass es keinen Sinn hat, PREG_PATTERN_ORDER zusammen mit PREG_SET_ORDER zu verwenden):

PREG_PATTERN_ORDER

Ordnet die Ergebnisse so an, dass $matches[0] ein Array von Übereinstimmungen mit dem kompletten Suchmuster ist, $matches[1] ein Array von Zeichenketten, die auf das erste eingeklammerte Teilsuchmuster passen und so weiter.

<?php
preg_match_all
("|<[^>]+>(.*)</[^>]+>|U",
    
"<b>Beispiel: </b><div align=left>das ist ein Test</div>",
    
$ausgabePREG_PATTERN_ORDER);
echo 
$ausgabe[0][0] . ", " $ausgabe[0][1] . "\n";
echo 
$ausgabe[1][0] . ", " $ausgabe[1][1] . "\n";
?>

Das oben gezeigte Beispiel erzeugt folgende Ausgabe:

<b>Beispiel: </b>, <div align=left>das ist ein Test</div>
Beispiel: , das ist ein Test

Also enthält $ausgabe[0] ein Array von Zeichenketten, die auf das komplette Suchmuster passen und $ausgabe[1] ein Array von Zeichenketten, die sich zwischen Tags befinden.

PREG_SET_ORDER

Ordnet die Ergebnisse so an, dass $matches[0] ein Array aus dem ersten Satz von Übereinstimmungen ist, $matches[1] ein Array aus dem zweiten Satz von Übereinstimmungen und so weiter.

<?php
preg_match_all
("|<[^>]+>(.*)</[^>]+>|U",
    
"<b>Beispiel: </b><div align=\"left\">das ist ein Test</div>",
    
$ausgabePREG_SET_ORDER);
echo 
$ausgabe[0][0] . ", " $ausgabe[0][1] . "\n";
echo 
$ausgabe[1][0] . ", " $ausgabe[1][1] . "\n";
?>

Das oben gezeigte Beispiel erzeugt folgende Ausgabe:

<b>Beispiel: </b>, Beispiel:
<div align="left">das ist ein Test</div>, das ist ein Test

PREG_OFFSET_CAPTURE

Wenn dieses Flag gesetzt ist, wird mit jeder gefundenen Übereinstimmung der dazugehörige Versatz in der Zeichenkette zurückgegeben. Beachten Sie, dass dies den Wert von matches in ein Array ändert, in dem jedes Element ein Array ist, das aus der übereinstimmenden Zeichenkette als Element 0 und deren Stelle in subject als Element 1 besteht.

Falls kein Flag für die Anordnung angegeben wurde, wird PREG_PATTERN_ORDER angenommen.

offset

Normalerweise beginnt die Suche am Anfang der Zeichenkette. Der optionale Parameter offset kann verwendet werden, um eine andere Stelle in Bytes anzugeben, ab der gesucht werden soll.

Hinweis:

Die Verwendung von offset entspricht nicht der Übergabe von substr($zeichenkette, $versatz) an Stelle der Zeichenkette an preg_match_all(), weil pattern Angaben wie zum Beispiel ^, $ oder (?<=x) enthalten kann. Für Beispiele siehe preg_match().

Rückgabewerte

Gibt die Anzahl der Übereinstimmungen mit dem kompletten Suchmuster zurück (die auch Null sein kann) oder FALSE, falls ein Fehler auftrat.

Changelog

Version Beschreibung
5.4.0 Der Parameter matches ist nun optional.
5.3.6 Gibt FALSE zurück, wenn offset größer als die Länge von subject ist.
5.2.2 Benannte Teilsuchmuster (named subpatterns) akzeptieren nun die Syntaxen (?<name>) und (?'name') sowie (?P<name>). Vorherige Versionen akzeptierten nur (?P<name>).
4.3.3 Den Parameter offset hinzugefügt
4.3.0 Das Flag PREG_OFFSET_CAPTURE hinzugefügt

Beispiele

Beispiel #1 Alle Telefonnummern aus einem Text holen.

<?php
preg_match_all
("/\(?  (\d{3})?  \)?  (?(1)  [\-\s] ) \d{3}-\d{4}/x",
                
"Wählen Sie 555-1212 oder 1-800-555-1212"$telefon);
?>

Beispiel #2 Zusammengehörende HTML-Tags finden (gierig)

<?php
// Das \\2 ist ein Beispiel für Rückreferenzierung. Es teilt pcre mit, dass
// der reguläre Ausdruck auf den für das zweite Klammerpaar gefundenen
// Ausdruck selbst, also in diesem Fall auf den für ([\w]+) gefundenen
// Ausdruck passen muss.
// Der zusätzliche Backslash wird wegen der doppelten Anführungsstriche
// benötigt.
$html "<b>fett gedruckter Text</b><a href=howdy.html>klick mich an</a>";

preg_match_all("/(<([\w]+)[^>]*>)(.*?)(<\/\\2>)/"$html$trefferPREG_SET_ORDER);

foreach (
$treffer as $wert) {
  echo 
"gefunden: " $wert[0] . "\n";
  echo 
"Teil 1: " $wert[1] . "\n";
  echo 
"Teil 2: " $wert[2] . "\n";
  echo 
"Teil 3: " $wert[3] . "\n";
  echo 
"Teil 4: " $wert[4] . "\n\n";
}
?>

Das oben gezeigte Beispiel erzeugt folgende Ausgabe:

gefunden: <b>fett gedruckter Text</b>
Teil 1: <b>
Teil 2: b
Teil 3: fett gedruckter Text
Teil 4: </b>

gefunden: <a href=howdy.html>klick mich an</a>
Teil 1: <a href=howdy.html>
Teil 2: a
Teil 3: klick mich an
Teil 4: </a>

Beispiel #3 Benannte Teilsuchmuster (named subpatterns)

<?php

$str 
= <<<FOO
a: 1
b: 2
c: 3
FOO;

preg_match_all('/(?P<name>\w+): (?P<zahl>\d+)/'$str$treffer);

/* Folgendes funktioniert ab PHP 5.2.2 (PCRE 7.0) ebenfalls, für die
 * Rückwärtskompatibilität wird aber die vorherige Form empfohlen. */
// preg_match_all('/(?<name>\w+): (?<zahl>\d+)/', $str, $treffer);

print_r($treffer);

?>

Das oben gezeigte Beispiel erzeugt folgende Ausgabe:

Array
(
    [0] => Array
        (
            [0] => a: 1
            [1] => b: 2
            [2] => c: 3
        )

    [name] => Array
        (
            [0] => a
            [1] => b
            [2] => c
        )

    [1] => Array
        (
            [0] => a
            [1] => b
            [2] => c
        )

    [zahl] => Array
        (
            [0] => 1
            [1] => 2
            [2] => 3
        )

    [2] => Array
        (
            [0] => 1
            [1] => 2
            [2] => 3
        )

)

Siehe auch



add a note add a note User Contributed Notes
preg_match_all
mr davin
12-Jul-2007 11:57
<?php
// Returns an array of strings where the start and end are found
   
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);

/* Results in
(
    [0] =>  6
    [1] =>  all the
)
*/
?>
Han Jun Kwang (me -at- hjk.ikueb.com)
05-Jul-2007 09: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
27-Jun-2007 08: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 03: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) {
 
// WARNING! - All this function does is to correct offsets, nothing else:
  //
 
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);
   
//
    // (code is independent of PREG_PATTER_ORDER / PREG_SET_ORDER)

 
return $ret;
  }

?>
sam at NOSPAM dot aigc dot net
03-Nov-2006 10: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 = "&nbsp; &nbsp; ";
    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 04:11
I refurnished connum at DONOTSPAMME dot googlemail dot com autoCloseTags function:
<?php
/**
 * close all open xhtml tags at the end of the string
 *
 * @author Milian Wolff <http://milianw.de>
 * @param string $html
 * @return string
 */
function closetags($html){
 
#put all opened tags into an array
 
preg_match_all("#<([a-z]+)( .*)?(?!/)>#iU",$html,$result);
 
$openedtags=$result[1];

 
#put all closed tags into an array
 
preg_match_all("#</([a-z]+)>#iU",$html,$result);
 
$closedtags=$result[1];
 
$len_opened = count($openedtags);
 
# all tags are closed
 
if(count($closedtags) == $len_opened){
    return
$html;
  }
 
$openedtags = array_reverse($openedtags);
 
# close tags
 
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 09: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)
{
       
//rfc2822 token setup
       
$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))";
       
//$cfws           = $fws; //an alternative to comments
       
$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)+";

       
//output length of string (just so you see how f**king long it is)
       
echo(strlen($address_list) . " ");

       
//apply expression
       
preg_match_all("/^$address_list$/", $string, $array, PREG_SET_ORDER);

        return
$array;
};
?>
mnc at u dot nu
03-Feb-2006 07: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
01-Feb-2006 04: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 09: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
09-Apr-2005 12:42
This function converts all HTML style decimal character code to hexadecimal code.
ex) Hi &#959; &#9674; Dec  ->  Hi &#x03BF; &#x25CA; 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 &#x03BF; &#x25CA; Hex  ->  Hello &#959; &#9674; 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 03: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 :-)

preg_match> <preg_last_error
Last updated: Fri, 18 May 2012