0

I am trying to process something similar like shrotcode via preg_replace_callback function:

$new_content = preg_replace_callback("|\[BLOCK\s?(TYPE=[0-9a-z\/]+)?\s?(TEXT=[a-z]+)?\s?(LAST)?\s?\]((?:(?!BLOCK).)*)\[\/BLOCK\]|","block",$content);

The subject ($content) is for example this:

[BLOCK TYPE=1/2 TEXT=right LAST]
<ul><li>something</li>
</ul>
[/BLOCK]
[BLOCK TYPE=1/2 TEXT=right LAST][NEXTSHORTCODE=something][/BLOCK]
[BLOCK TYPE=1/2 TEXT=right LAST]123[/BLOCK]

I met a problem:

Function preg_replace_callback matches whole subject (from BLOCK to last /BLOCK) instead of first occurance of /BLOCK. I wanted to solve it excluding string BLOCK ((?:(?!BLOCK).)*) from inner content of a shortcode but it do not work with other characters like new line etc.

You can see my tries here: http://rubular.com/r/0AqadXVdON

Thank you for advise and sorry for bad english.

O. Jones
  • 103,626
  • 17
  • 118
  • 172

3 Answers3

0

You need to use a so-called lazy match expression for your closing tag.

Your regex ends with \[\/BLOCK\].

Try ending it with \[\/BLOCK\]? instead. That will make it match the first occurrence it finds (lazy) rather than the last occurrence(greedy).

O. Jones
  • 103,626
  • 17
  • 118
  • 172
0

Adding to what Ollie said, if you don't care about the TYPE and other references inside a BLOCK and just want to replace all blocks, you could go with something as simple as:

$regex = "~(?s)\[BLOCK.*?/BLOCK]~";
$new_content = preg_replace_callback($regex, $block, $subject);
function block($m) {
  // replace magic
  return $something;
}
zx81
  • 41,100
  • 9
  • 89
  • 105
0

You are missing the m switch.

Try this on instead:

\[BLOCK\s?(TYPE=[0-9a-z\/]+)?\s?(TEXT=[a-z]+)?\s?(LAST)?\s?\]((?:(?!BLOCK).)*)\[\/BLOCK\]

Demo

http://rubular.com/r/7ijXdrhERE

Pedro Lobito
  • 94,083
  • 31
  • 258
  • 268