0

I'm creating a templating system that can allow a user to create a template and use the selected/dynamic value from the original string.

Example:

Original string:
Lorem ipsum dolor (Hello world) sit YEAH amet

Template:
consectetur adipiscing elit, sed do @BETWEEN("dolor (",") sit") eiusmod tempor incididunt ut labore et dolore @BEWTEEN("sit","amet")

Output:
consectetur adipiscing elit, sed do Hello world eiusmod tempor incididunt ut labore et dolore YEAH

I'm trying to get the @BETWEEN from the template by using regex

@BETWEEN\([^\(\)]+\)

But it did not work due to the bracket symbol in the @BETWEEN bracket. I'm not very good at regex. Can anyone give me suggestion on how to enhance the regex or any other method to get the @BETWEEN function from the template

Nick
  • 138,499
  • 22
  • 57
  • 95
Deno
  • 434
  • 4
  • 16
  • 1
    Avoid dealing with nested content using regex. – Pushpesh Kumar Rajwanshi May 03 '19 at 09:03
  • According to your template no substitution should occur as there is no value between `dolor (` and `) sit` in the original string – Nick May 03 '19 at 09:05
  • Yeah, it seems the example is wrong. – KIKO Software May 03 '19 at 09:05
  • @thehennyy you're not obliged to escape the backets in a character class `[]` – Kaddath May 03 '19 at 09:06
  • Sorry for forgot escape special character in the sample. But it still not working even escaped the special character. – Deno May 03 '19 at 09:07
  • You can use `@BETWEEN\(.*\)` to capture everything between first `(` and last `)` but it won't work if you have multiple parenthesis present ahead, which is why I suggested not to use regex. – Pushpesh Kumar Rajwanshi May 03 '19 at 09:07
  • Regular expressions [should not be used in normal programming](https://hackernoon.com/for-the-love-of-jeez-stop-using-regex-in-software-3a916e2c5987). Especially if you don't understand them. Try to write a normal algorithm instead, something that you, and others, can understand. – KIKO Software May 03 '19 at 09:08
  • Usually in templating systems, placeholders are delimited by `{}`, it could partially solve your problem, even if it's not a definitive solution, as @PushpeshKumarRajwanshi says you're going to have hard times with nesting – Kaddath May 03 '19 at 09:09

1 Answers1

1

Since your template pattern looks for strings enclosed in quotes e.g. "dolor (", you can find those values, create a regex out of them to look for the matching string in your original string, and then use that match to replace the patterns in the template with the value from the original string.

$string = 'Lorem ipsum dolor (Hello world) sit YEAH amet';
$template = 'consectetur adipiscing elit, sed do @BETWEEN("dolor (",") sit") eiusmod tempor incididunt ut labore et dolore @BETWEEN("sit","amet")';

preg_match_all('/@BETWEEN\("([^"]+)","([^"]+)"\)/', $template, $matches, PREG_SET_ORDER);
foreach ($matches as $temp) {
    $regex = '/' . preg_quote($temp[1]) . '(.*?)' . preg_quote($temp[2]) . '/';
    preg_match($regex, $string, $replacement);
    $template = preg_replace('/' . preg_quote($temp[0]) . '/', $replacement[1], $template);
}
echo $template;

Output:

consectetur adipiscing elit, sed do Hello world eiusmod tempor incididunt ut labore et dolore YEAH 

Note that this will not work if the strings in your template patterns also contain escaped quotes. To implement this functionality in that case, you would need to use a regex derived from something like this question.

Nick
  • 138,499
  • 22
  • 57
  • 95