Awlad Liton
Awlad Liton

Reputation: 9351

Get all pipe-delimited words inside of all curly braced expressions in a string

I have a string like this:

$str = "{It|This} part, but also {spin|rotation} the words";

i want to split {It|This} and {spin|rotation} to It, This ,spin,rotation by regular expression.

I need regular expression for this.

$str = "{It|This} part, but also {spin|rotation} the words";
$pattern =''; // need a pttern here
$arr = preg_split($pattern,$str);
print_r($arr);

Upvotes: 2

Views: 83

Answers (2)

mickmackusa
mickmackusa

Reputation: 47764

In a single regex, use the continue metacharacter \G.

/
(?:            #non-capturing group start
   \G(?!^)     #match the position immediately after a previous match but not the start of the string
   \|          #match a pipe
   |           #or
   [^{]*       #match irrelevant non-enclosure segment
   {           #match start of curly braced enclosure
   (?=[^}]+})  #lookahead for completion of the curly braced enclosure
)              #end of capturing group
\K             #forget any previously matched characters
[^}|]+         #match non-pipe, non-closing-curly-brace characters
/

Implementation: (Demo)

$str = "{It|This} part, not|that but also {spin|rotation} the words";

preg_match_all(
    '/(?:\G(?!^)\||[^{]*{(?=[^}]+}))\K[^}|]+/',
    $str,
    $m
);
var_export(implode(',', $m[0]);

$m's output:

array (
  0 => 
  array (
    0 => 'It',
    1 => 'This',
    2 => 'spin',
    3 => 'rotation',
  ),
)

If you actually wanted to replace whole placeholder expressions with a randomly selected option within the placeholders, then preg_replace_callback() is most appropriate. Demo

echo preg_replace_callback(
         '/{([^}]+)}/',
         function ($m) {
             $opts = explode('|', $m[1]);
             return $opts[array_rand($opts)];
         },
         $str
     );

One of the four possible outputs:

It part, not|that but also rotation the words

Upvotes: -1

Explanation :

Using preg_match_all() the content between the { and } are matched and those matches are cycled through via a foreach , exploding the argument by | and then finally doing an implode()

The code..

$str = "{It|This} part, but also {spin|rotation} the words";
preg_match_all('/{(.*?)}/', $str, $matches);
foreach($matches[1] as $v)
{
    $new_val[]=explode('|',$v);
}
echo $new_val=implode(',',call_user_func_array('array_merge',$new_val));

OUTPUT :

It,This,spin,rotation

Demonstration

Upvotes: 2

Related Questions