Search code examples
phpregexpreg-replacepreg-replace-callback

Converting string but leave characters wrapped in braces


  1. I'm converting a user input string (successfully but...)
  2. I would like to ignore characters wrapped in braces
  3. Also remove the braces in the final output

So for instance if I have this string:

$string = "[ABC] This & Text";

function make_post_type($string) {
  $needle   = array('-', ' ');
  $clean    = preg_replace("/[^a-zA-Z0-9_\s]/", "", strtolower($string)); // Remove special characters
  $haystack = preg_replace('!\s+!', ' ', $clean); // Now remove extra spaces

  return str_replace($needle, '_', $haystack);
}

returns abc_this_text

I would like to return ABC_this_text


Solution

  • You may use this regex code in preg_replace_callback:

    function replc($str) {
       return preg_replace_callback (
          '/\[([^]]*)\]|{([^}]*)}|([^][{}]+)/',
          function ($m) {
             return (isset($m[1])?$m[1]:"") .
                    (isset($m[2])?$m[2]:"") .
                     (isset($m[3]) ?
                     preg_replace('/\W+/', '_', strtolower($m[3])) : "");
          },
          $str
       );
    }
    

    Call it as:

    echo replc( "[ABC] This & Text" );
    ABC_this_text
    
    echo replc( "abc.Xyz {PQR} Foo-Bar [ABC] This & Text" );
    abc_xyz_PQR_foo_bar_ABC_this_text
    

    1st RegEx Details:

    • [([^]]*)\]: If we encounter [...] then capture inner part in group #1
    • |: OR
    • {([^}]*)}: If we encounter {...} then capture inner part in group #2
    • |: OR
    • [^][{}]+: Match 1+ character that is not [ and ] and { and } and capture in group #3

    2nd RegEx:

    • \W+: match 1+ non-word character to be replaced by _