Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>You did not provide an example, so I compiled one on my own. The working solution I came up with is using a simple callback function:</p> <pre><code>$url = 'http://example.com/'; $title = 'Make it Complex \4'; $subject = 'Call \\4 " $me an url'; $pattern = '/(.*)an()( )(url)/'; $replace = function($m) use ($url, $title) { return "$m[1]$url$m[3]$title$m[4]"; }; $result = preg_replace_callback($pattern, $replace, $subject); </code></pre> <p>Result:</p> <pre><code>Call \4 " $me http://example.com/ Make it Complex \4url </code></pre> <p>The callback function is a so called <a href="http://www.php.net/manual/en/functions.anonymous.php" rel="nofollow">anonymous function <sup><em>Docs</em></sup></a> which makes it easy to edit the code in place.</p> <p>In case you need this more often you can put that into a function of your own, probably to make it more re-useable. You can even go to that far and create yourself your own pattern to replace subgroup matches and variables. For examle <code>{\1}</code> stands for the subpattern 1 match, <code>{$2}</code> for the second variable. Wrapping this into a function of it's own:</p> <pre><code>$patternf = function() { $values = func_get_args(); $mask = $values ? array_shift($values) : NULL; return function($matches) use ($mask, $values) { $parts = preg_split('/({[\\\\\\$][0-9]{1,3}})/', $mask, 0, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); foreach($parts as &amp;$part) if (preg_match('/^{([\\\\\\$])([0-9]{1,3})}$/', $part, $p)) $part = $p[1] == '\\' ? $matches[(int)$p[2]] : $values[$p[2]-1]; return implode('', $parts); }; }; </code></pre> <p>Would allow you to make the replacement more handy:</p> <pre><code>$replace = $patternf('{\1}{$1}{\3}{$2}{\4}', $url, $title); $result = preg_replace_callback($pattern, $replace, $subject); </code></pre> <p><a href="http://codepad.viper-7.com/SeRVHw" rel="nofollow">Demo</a>. Wrapping this into a function of it's own:</p> <pre><code>function preg_replace_subst($pattern, $replace, $subject) { $values = func_get_args(); $pattern = array_shift($values); $mask = array_shift($values); $subject = array_shift($values); $callback = function($matches) use ($mask, $values) { $parts = preg_split('/({[\\\\\\$][0-9]{1,3}})/', $mask, 0, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); foreach($parts as &amp;$part) if (preg_match('/^{([\\\\\\$])([0-9]{1,3})}$/', $part, $p)) $part = $p[1] == '\\' ? $matches[(int)$p[2]] : $values[$p[2]-1]; return implode('', $parts); }; return preg_replace_callback($pattern, $callback, $subject); } </code></pre> <p>Would give it an easy interface:</p> <pre><code>$url = 'http://example.com/'; $title = 'Make it Complex \4'; $subject = 'Call \\4 " $me an url'; $pattern = '/(.*)an()( )(url)/'; $replace = '{\1}{$1}{\3}{$2}{\4}'; $result = preg_replace_subst($pattern, $replace, $subject, $url, $title); </code></pre> <p>But with many substitution variables it should be possible to pass them as an array probably otherwise it gets a bit lengthy.</p> <h3>Using the <code>e</code> modifier with <code>preg_replace</code> (and why it does not work)</h3> <p>When using the <code>e</code> modifier, the matches get replaced in the replace string and it then get's evaluated. As other variables do not get escaped, the matches do interfere with PHP variable substitution, which is dangerous:</p> <pre><code>$url = 'http://example.com/'; $title = 'Make it Complex \4'; $subject = 'Call me an url.'; $pattern = '/(.*)an()( )(url)/e'; $replace = '"$1{$url}$3{$title}$4"'; $result = preg_replace($pattern, $replace, $subject); </code></pre> <p>Outputs:</p> <pre><code>Call me http://example.com/ Make it Complex \4url. </code></pre> <p>As written, the first <code>e</code>-modifier example is broken because <code>$</code> won't get escape in <code>$subject</code>, so PHP would have looked for unset variables. That's dangerous, too. I came up with a variant, it solves that issue but it can't handle double-quotes in the subject:</p> <pre><code>$url = 'http://example.com/'; $title = 'Make it Complex \4'; $subject = 'Call \\4 " $me an url'; $pattern = '/(.*)an()( )(url)/e'; $replace = "'\$1'.\$url.'\$3'.\$title.'$4'"; </code></pre> <p>Output:</p> <pre><code>Call \4 \" $me http://example.com/ Make it Complex \4url ^ problem, not in input. </code></pre> <p>So not really fool-proof, that's why it needs the callback function because it gets the matching sub-patterns unquoted.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload