4

I am using php 5 to parse a string. My input string looks like the following:

{Billion is|Millions are|Trillion is} {an extremely |a| a generously | a very} { tiny|little |smallish |short |small} stage in a vast {galactic| |large|huge|tense|big |cosmic} {universe|Colosseum|planet|arena}.

Find below my minimum viable example:

<?php

function process($text)
{
    return preg_replace_callback('/\[(((?>[^\[\]]+)|(?R))*)\]/x', array(
        $this,
        'replace'
    ), $text);
}
function replace($text)
{
    $text  = $this->process($text[1]);
    $parts = explode('|', $text);
    return $parts[array_rand($parts)];
}

$text = "{Billion is|Millions are|Trillion is} {an extremely |a| a generously | a very} { tiny|little |smallish |short |small} stage in a vast {galactic| |large|huge|tense|big |cosmic} {universe|Colosseum|planet|arena}.";

$res = process($text);

echo $res;

As you can see I am trying to parse the following pattern f.ex.: {Billion is|Millions are|Trillion is} using the above regex, /\[(((?>[^\[\]]+)|(?R))*)\]/x.

As a result I am getting the same string as inputted. I would like to get as an output for example:

Billion is a very little stage in a vast huge arena.

Any suggestions what I am doing wrong?

3
  • 1
    Please add the input string. Commented Aug 12, 2018 at 18:18
  • 1
    @Rafael Please find my updated question. Furthermore, my input string is also included in the example code. Commented Aug 12, 2018 at 18:23
  • Indeed, my mistake. Really interesting question though. Commented Aug 12, 2018 at 19:23

1 Answer 1

3

How would your current code generate anything.

  1. Your regex doesn't fit. It matches nested bracketed stuff and not braced. Try{([^}]*)} for capturing everything inside {...} to $m[1] if there are no nested braces.

  2. Read about preg_replace_callback(). The second argument can not be an array.

A working code with some further adjustments could look like this:

function process($text) {
  return preg_replace_callback('/{([^}]*)}/', 'replace', $text);
}

function replace($m) {
  $parts = explode('|', $m[1]);
  shuffle($parts);
  return $parts[0];
}

$text = "{Billion is|Millions are|Trillion is} {an extremely|a|a generously|a very} {tiny|little|smallish|short|small} stage in a vast {galactic||large|huge|tense|big|cosmic} {universe|Colosseum|planet|arena}.";

echo process($text);

Billion is a generously short stage in a vast Colosseum.

Here is a demo at eval.in

(you can also use an anonymous function if PHP >= 5.3)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.