ScotlandPHP 2019

preg_replace_callback_array

(PHP 7)

preg_replace_callback_arrayÉffectue une recherche de correspondance avec une expression régulière et remplace grâce à une fonction de rappel

Description

preg_replace_callback_array ( array $patterns_and_callbacks , mixed $subject [, int $limit = -1 [, int &$count ]] ) : mixed

Le comportement de cette fonction est similaire à preg_replace_callback(), à l'exception que les fonctions de rappel sont exécutéees à chaque masque.

Liste de paramètres

patterns_and_callbacks

Un tableau associatif qui établie une relation entre les masques (clés) et les fonctions de rappels (valeurs).

subject

La chaîne de caractères ou tableau qui contient les chaîne de caractères à chercher et remplacer.

limit

Le nombre maximum de remplacement pour chaque masque dans chaque chaîne de caractères subject. Par défaut -1 (aucune limite).

count

Si fournit, cette variable sera remplit avec le nombre de remplacement effectué.

Valeurs de retour

preg_replace_callback_array() retourne un tableau si le paramètre subject est un tableau, ou sinon une chaîne de caractères. Lors d'une erreur la valeur de retour est NULL.

Si des correspondances sont trouvées, le nouveau sujet sera retourné, sinon subject sera retourné inchangé.

Exemples

Exemple #1 Exemple de preg_replace_callback_array()

<?php
$subject 
'Aaaaaa Bbb';

preg_replace_callback_array(
    [
        
'~[a]+~i' => function ($match) {
            echo 
strlen($match[0]), ' correspondances de "a" trouvées'PHP_EOL;
        },
        
'~[b]+~i' => function ($match) {
            echo 
strlen($match[0]), ' correspondances de "b" trouvées'PHP_EOL;
        }
    ],
    
$subject
);
?>

L'exemple ci-dessus va afficher :

6 correspondances de "a" trouvées
3 correspondances de "b" trouvées

Voir aussi

add a note add a note

User Contributed Notes 3 notes

up
9
drevilkuko at gmail dot com
3 years ago
finally!!!

before (<=php5.6):

<?php
        $htmlString
= preg_replace_callback(
           
'/(href="?)(\S+)("?)/i',
            function (&
$matches) {
                return
$matches[1] . urldecode($matches[2]) . $matches[3];
            },
           
$htmlString
       
);

       
$htmlString = preg_replace_callback(
           
'/(href="?\S+)(%24)(\S+)?"?/i', // %24 = $
           
function (&$matches) {
                return
urldecode($matches[1] . '$' . $matches[3]);
            },
           
$htmlString
       
);
?>

php7

<?php

        $htmlString
= preg_replace_callback_array(
            [
               
'/(href="?)(\S+)("?)/i' => function (&$matches) {
                    return
$matches[1] . urldecode($matches[2]) . $matches[3];
                },
               
'/(href="?\S+)(%24)(\S+)?"?/i' => function (&$matches) {
                    return
urldecode($matches[1] . '$' . $matches[3]);
                }
            ],
           
$htmlString
       
);
?>
up
3
Sz.
11 months ago
Based on some tests, I found these important traits of the function. (These would
be nice to see documented as part of its spec, e.g. for confirmation. Without that,
this is just experimental curiosity. Still better than guesswork, though! ;) )

1. Changes cascade over a subject across callbacks, i.e. a change made to a
   subject by a callback will be seen by the next callback, if its pattern matches
   the changed subject.
   (But a change made by a previous call of the *same* callback (on any subject)
   will not be seen by that callback again.)

2. The pattern + callback pairs will be applied in the order of their appearance
   in $patterns_and_callbacks.

3. The callback can't be null (or '') for a quick shortcut for empty replacements.

4. Overall, the algorithm starts iterating over $patterns_and_callbacks, and then
   feeds each $subject to the current callback, repeatedly for every single match
   of its pattern on the current subject (unlike "preg_match_all", that is, which
   can do the same in one go, returning the accumulated results in an array).

   This basically means that the "crown jewel", an even more efficient function:
   "preg_replace_all_callback_array" is still missing from the collection.

   (Of course, that would better fit a new design of the regex API, where one
   API could flexibly handle various different modes via some $flags = [] array.)

5. (This last one is not specific to this function, but inherent to regexes, OTOH,
   it's probably more relevant here than anywhere else in PHP's regex support.)

   Even apparently simple cases can generate a crazy (and difficult-to-predict)
   number of matches, and therefore callback invokations, so remember the set
   $limit, where affordable. But, of course, try to sharpen your patterns first!

   E.g. use ^...$ anchoring to avoid unintended extra calls on matching substrings
   of a subject, (I.e. '/.*/', without anchoring, would match twice: once for the
   whole subject, and then for a trailing empty substring -- but I'm not quite sure
   this should actually be correct behavior, though.)
up
-2
jfcherng at NOSPAM dot gmail dot com
3 years ago
Here's a possible alternative in older PHP.

<?php

// if (!function_exists('preg_replace_callback_array')) {

function preg_replace_callback_array (array $patterns_and_callbacks, $subject, $limit=-1, &$count=NULL) {
   
$count = 0;
    foreach (
$patterns_and_callbacks as $pattern => &$callback) {
       
$subject = preg_replace_callback($pattern, $callback, $subject, $limit, $partial_count);
       
$count += $partial_count;
    }
    return
preg_last_error() == PREG_NO_ERROR ? $subject : NULL;
}

// }

?>
To Top