0
votes

Looking for a regular expression for preg_match_all that can detect a variable encapsulated in a % in a body of text like so:

Lorem ipsum dolor sit amet, consectetur adipisicing %variable1%, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip %variable2% ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa %variable3% qui officia deserunt mollit anim id est laborum.

Where the variables to be detected are encapsulated in % symbols. The variables can include lowercase letters (a-z), numbers (0-9) and the hyphen (-). I would like to return the names of the variables in the % signs in an array like follows, but cant get it to match.

Array (
    [0] => 'variable1',
    [1] => 'variable2',
    [3] => 'variable3'
}

Any advice?

3
Try /%(.+?)%/, then refine.elclanrs
~%([^%]+)%~ is more explicitHamZa

3 Answers

0
votes

Do like this

<?php
$txt='Lorem ipsum dolor sit amet, consectetur adipisicing %variable1%, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip %variable2% ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa %variable3% qui officia deserunt mollit anim id est laborum.';
preg_match_all('/%(.*?)%/', $txt, $matches);
print_r($matches[1]);

OUTPUT :

Array
(
    [0] => variable1
    [1] => variable2
    [2] => variable3
)

Demo

0
votes
<?php

$text = <<<TEXT
Lorem ipsum dolor sit amet, consectetur adipisicing %variable1%, sed do eiusmod tempor incididunt 
ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco 
laboris nisi ut aliquip %variable2% ex ea commodo consequat. Duis aute irure dolor in reprehenderit 
in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat
non proident, sunt in culpa %variable3% qui officia deserunt mollit anim id est laborum.
TEXT;

preg_match_all('/%(?P<variables>.*?)%/', $text, $matches);
print_r($matches['variables']);

Will output:

Array
(
    [0] => variable1
    [1] => variable2
    [2] => variable3
)

Bonus

function process ($text, array $variables) {
  preg_match_all('/(?P<variables>%(.*?)%)/', $text, $matches, PREG_OFFSET_CAPTURE);
  if (isset($matches['variables'])) {
    foreach (array_column($matches['variables'], 0, 1) AS $offset => $var) {
      $value = isset($variables[$var]) ? $variables[$var] : NULL;
      $text = substr_replace($text, $value, $offset, strlen($var));
    }

    return $text;
  }

  // whoopz!
  return NULL;
}

Using it (PHP 5.4+) echo process($text, ['%variable1%' => 'hello']);
Server version is less than 5.4 ? you can download array_column function at https://github.com/ramsey/array_column.

0
votes

Not a good idea if you ask me because you may end up getting "variables" between things like 25% and 35%. Now, if you assume that the variable name cannot start with a space, or even better, can only start with a letter, then you could use something like this:

'/%([a-zA-Z][a-zA-Z0-9_]*?)%/'

as the regex.

Using '.' like others mentioned will get you in trouble.

Note that there is a preg_replace_callback() function too, in case you wanted to replace the variable with something else.