Search code examples
phpregexpreg-matchpreg-match-allregular-language

Regex to match specific string not enclosed by another, different specific string


I need a regex to match a string not enclosed by another different, specific string. For instance, in the following situation it would split the content into two groups: 1) The content before the second {Switch} and 2) The content after the second {Switch}. It wouldn't match the first {Switch} because it is enclosed by {my_string}'s. The string will always look like shown below (i.e. {my_string}any content here{/my_string})

Some more  
  {my_string}
  Random content
  {Switch} //This {Switch} may or may not be here, but should be ignored if it is present
  More random content
  {/my_string}
Content here too
{Switch}
More content

So far I've gotten what is below which I know isn't very close at all:

(.*?)\{Switch\}(.*?)

I'm just not sure how to use the [^] (not operator) with a specific string versus different characters.


Solution

  • Try this simple function:

    function find_content()

    function find_content($doc) {
      $temp = $doc;
      preg_match_all('~{my_string}.*?{/my_string}~is', $temp, $x);
      $i = 0;
      while (isset($x[0][$i])) {
        $temp = str_replace($x[0][$i], "{REPL:$i}", $temp);
        $i++;
        }
      $res = explode('{Switch}', $temp);
      foreach ($res as &$part) 
        foreach($x[0] as $id=>$content)
          $part = str_replace("{REPL:$id}", $content, $part);
      return $res;
      }
    

    Use it this way

    $content_parts = find_content($doc); // $doc is your input document
    print_r($content_parts);
    

    Output (your example)

    Array
    (
        [0] => Some more
    {my_string}
    Random content
    {Switch} //This {Switch} may or may not be here, but should be ignored if it is present
    More random content
    {/my_string}
    Content here too
    
        [1] => 
    More content
    )