$re = '~(?(DEFINE)
   (?P<table>                     # To match nested table tags
      <table\b[^>]*>
         (?:
            (?!</?table\b[^>]*>).
         |
            (?&table)
         )*
      </table\s*>
   )
   (?P<paragraph>                 # To match nested p tags
      <p\b[^>]*>
         (?:
            (?!</?p\b[^>]*>).
         |
            (?¶graph)
         )*
      </p\s*>
   )
)
(?&table)(*SKIP)(*FAIL)           # Let\'s skip table tags
|
(?¶graph)                     # And match p tags~xsi';
$str = 'test <table><p>wuuut</p></table><p>foo bar</p> test1 <p>baz qux</p> test3';
preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);
// Print the entire match result
var_dump($matches);
Please keep in mind that these code samples are automatically generated and are not guaranteed to work. If you find any syntax errors, feel free to submit a bug report. For a full regex reference for PHP, please visit: http://php.net/manual/en/ref.pcre.php