www.webdeveloper.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 19

Thread: Having trouble with my preg_replace_callback()

  1. #1
    Join Date
    May 2006
    Posts
    245

    Having trouble with my preg_replace_callback()

    Hi,

    I have a function which converts text into a header format:

    Its nice because I can chose deliminators and exception

    This is the string version:
    PHP Code:
    function titleCase_str($string){
        
    $delimiters = array(" ""-"".""'""O'""Mc");
        
    $exceptions = array("and""to""of""das""dos""I""II""III""IV""V""VI");
        
    $string mb_convert_case($stringMB_CASE_TITLE"UTF-8");
        foreach (
    $delimiters as $dlnr => $delimiter) {
            
    $words explode($delimiter$string);
            
    $newwords = array();
            foreach (
    $words as $wordnr => $word) {
                if (
    in_array(mb_strtoupper($word"UTF-8"), $exceptions)) {
                    
    // check exceptions list for any words that should be in upper case
                    
    $word mb_strtoupper($word"UTF-8");
                } elseif (
    in_array(mb_strtolower($word"UTF-8"), $exceptions)) {
                    
    // check exceptions list for any words that should be in upper case
                    
    $word mb_strtolower($word"UTF-8");
                } elseif (!
    in_array($word$exceptions)) {
                    
    // convert to uppercase (non-utf8 only)
                    
    $word ucfirst($word);
                }
                
    array_push($newwords$word);
            }
            
    $string join($delimiter$newwords);
       }
    //foreach
       
    return $string;

    This works fine on a string like this:
    PHP Code:
    $the_title "this-that is. a test of the Mcdougal title";

    $test_title_out titleCase_str($the_title); 
    I get this output:

    This-That Is. A Test of The McDougal Title

    But I only want to apply this titleCase to titles within
    a body of text.

    So I have tried to convert the function to use an array input:

    PHP Code:
    function titleCase($matches){
        
    $string $matches[1];
        
    $delimiters = array(" ""-"".""'""O'""Mc");
        
    $exceptions = array("and""to""of""das""dos""I""II""III""IV""V""VI");
        
    $string mb_convert_case($stringMB_CASE_TITLE"UTF-8");
        foreach (
    $delimiters as $dlnr => $delimiter) {
            
    $words explode($delimiter$string);
            
    $newwords = array();
            foreach (
    $words as $wordnr => $word) {
                if (
    in_array(mb_strtoupper($word"UTF-8"), $exceptions)) {
                    
    // check exceptions list for any words that should be in upper case
                    
    $word mb_strtoupper($word"UTF-8");
                } elseif (
    in_array(mb_strtolower($word"UTF-8"), $exceptions)) {
                    
    // check exceptions list for any words that should be in upper case
                    
    $word mb_strtolower($word"UTF-8");
                } elseif (!
    in_array($word$exceptions)) {
                    
    // convert to uppercase (non-utf8 only)
                    
    $word ucfirst($word);
                }
                
    array_push($newwords$word);
            }
            
    $string join($delimiter$newwords);
       }
    //foreach
       
    return $string;

    And now to use the function in the preg_replace_callback()

    PHP Code:
    $test "now for a test. [hd2]this is header2[/hd] test! does THIS [hd3] this is header3 [/hd]THING work? we will soon know # willl we not ? see you soon";

    $test_output2 preg_replace_callback(
                    
    "/(\hd[1-6](.+?)\[\/hd\])/",
                    
    "titleCase",
                    
    $test); 

    But my headings don't get converted

    I get this output:

    now for a test. [hd2]this is header2[/hd] test! does THIS [hd3] this is header3 [/hd]THING work? we will soon know # willl we not ? see you soon

    Can anyone see what I have done wrong ?

    Thanks.



    .
    Developers Choice Revealed:
    www.devchoice.info
    Which host has won, and why ?

  2. #2
    Join Date
    May 2006
    Posts
    245
    Does anyone know about these preg_replace_callback() ???

    Please help.

    Thanks.



    .
    Developers Choice Revealed:
    www.devchoice.info
    Which host has won, and why ?

  3. #3
    Join Date
    May 2004
    Location
    chennai, tamil nadu, India
    Posts
    445
    Quote Originally Posted by jeddik View Post
    Does anyone know about these preg_replace_callback() ???

    Please help.

    Thanks.



    .
    You can have this as a starting point and then refine it further

    Code:
    <?php
    
    $test = "now for a test. [hd2]this is header2[/hd] test! does THIS [hd3] this is header3 [/hd]THING work? we will soon know # willl we not ? see you soon";
    
    $test_output2 = preg_replace_callback(
                    "/\[hd[1-6]\](.+?)\[\/hd\]/",
                    "titleCase_str",
                    $test); 
    
    print $test_output2;
    
    
    function titleCase_str($string){
    $string = $string[1];
        $delimiters = array(" ", "-", ".", "'", "O'", "Mc");
        $exceptions = array("and", "to", "of", "das", "dos", "I", "II", "III", "IV", "V", "VI");
        $string = mb_convert_case($string, MB_CASE_TITLE, "UTF-8");
        foreach ($delimiters as $dlnr => $delimiter) {
            $words = explode($delimiter, $string);
            $newwords = array();
            foreach ($words as $wordnr => $word) {
                if (in_array(mb_strtoupper($word, "UTF-8"), $exceptions)) {
                    // check exceptions list for any words that should be in upper case
                    $word = mb_strtoupper($word, "UTF-8");
                } elseif (in_array(mb_strtolower($word, "UTF-8"), $exceptions)) {
                    // check exceptions list for any words that should be in upper case
                    $word = mb_strtolower($word, "UTF-8");
                } elseif (!in_array($word, $exceptions)) {
                    // convert to uppercase (non-utf8 only)
                    $word = ucfirst($word);
                }
                array_push($newwords, $word);
            }
            $string = join($delimiter, $newwords);
       }//foreach
       return $string; 
    }
    
    ?>
    Chris, Senior Developer,
    Php laravel developers,
    www.chrisranjana.com

  4. #4
    Join Date
    May 2006
    Posts
    245
    Not quite sure what you mean ?

    You have taken the function that does work ( titleCase_str () )
    and inserted this line $string = $string[1];.

    And this breaks the function.

    Anyway ...

    I took the same line out of the other function titleCase()

    But unfortunately, it did not make it work, I get the same result:
    These are my functions:

    PHP Code:

    function titleCase_str($string){
        
    $delimiters = array(" ""-"".""'""O'""Mc");
        
    $exceptions = array("and""to""of""das""dos""I""II""III""IV""V""VI");
        
    $string mb_convert_case($stringMB_CASE_TITLE"UTF-8");
        foreach (
    $delimiters as $dlnr => $delimiter) {
            
    $words explode($delimiter$string);
            
    $newwords = array();
            foreach (
    $words as $wordnr => $word) {
                if (
    in_array(mb_strtoupper($word"UTF-8"), $exceptions)) {
                    
    // check exceptions list for any words that should be in upper case
                    
    $word mb_strtoupper($word"UTF-8");
                } elseif (
    in_array(mb_strtolower($word"UTF-8"), $exceptions)) {
                    
    // check exceptions list for any words that should be in upper case
                    
    $word mb_strtolower($word"UTF-8");
                } elseif (!
    in_array($word$exceptions)) {
                    
    // convert to uppercase (non-utf8 only)
                    
    $word ucfirst($word);
                }
                
    array_push($newwords$word);
            }
            
    $string join($delimiter$newwords);
       } 
    // end foreach
       
    return $string;
    }    


    function 
    titleCase($matches){
        
    $delimiters = array(" ""-"".""'""O'""Mc");
        
    $exceptions = array("and""to""of""das""dos""I""II""III""IV""V""VI");
        
    $string mb_convert_case($stringMB_CASE_TITLE"UTF-8");
        foreach (
    $delimiters as $dlnr => $delimiter) {
            
    $words explode($delimiter$string);
            
    $newwords = array();
            foreach (
    $words as $wordnr => $word) {
                if (
    in_array(mb_strtoupper($word"UTF-8"), $exceptions)) {
                    
    // check exceptions list for any words that should be in upper case
                    
    $word mb_strtoupper($word"UTF-8");
                } elseif (
    in_array(mb_strtolower($word"UTF-8"), $exceptions)) {
                    
    // check exceptions list for any words that should be in upper case
                    
    $word mb_strtolower($word"UTF-8");
                } elseif (!
    in_array($word$exceptions)) {
                    
    // convert to uppercase (non-utf8 only)
                    
    $word ucfirst($word);
                }
                
    array_push($newwords$word);
            }
            
    $string join($delimiter$newwords);
       } 
    // end foreach
       
    return $string;
    }    
        
    // END OF FUNCTIONS
        
    // Test Functions

    $test "now for a test. [hd2]this is header2[/hd] test! does THIS [hd3] this is header3 [/hd]THING work? we will soon know # willl we not ? see you soon";

    $the_title "this-that is. a test of the Mcdougal title";

    $test_title_out titleCase_str($the_title);
                
    $test_output2 preg_replace_callback(
        
    "/(\hd[1-6](.+?)\[\/hd\])/",
        
    "titleCase",
        
    $test);

                    
    echo 
    "<br><br>Test_title_out<br>$test_title_out<br><br>";
        
    echo 
    "<br><br>Test_output 2<br>$test_output2<br><br>"

    And the output:

    Test_title_out
    This-That Is. A Test of The McDougal Title

    Test_output 2
    now for a test. [hd2]this is header2[/hd] test! does THIS [hd3] this is header3 [/hd]THING work? we will soon know # willl we not ? see you soon
    Developers Choice Revealed:
    www.devchoice.info
    Which host has won, and why ?

  5. #5
    Join Date
    May 2006
    Posts
    245
    It looks OK to me,

    I can not see what I did wrong here ...


    .
    Developers Choice Revealed:
    www.devchoice.info
    Which host has won, and why ?

  6. #6
    Join Date
    Dec 2011
    Location
    Centurion, South Africa
    Posts
    795
    My turn

    PHP Code:
    <?php

        
    function titleCase($matches)
        {
            
    $string is_array($matches) ? $matches[1] : $matches;
            
    $delimiters = array(" ""-"".""'""O'""Mc");
            
    $exceptions = array("and""to""of""das""dos""I""II""III""IV""V""VI");
            
    $string mb_convert_case($stringMB_CASE_TITLE"UTF-8");
            foreach (
    $delimiters as $dlnr => $delimiter) {
                
    $words explode($delimiter$string);
                
    $newwords = array();
                foreach (
    $words as $wordnr => $word) {
                    if (
    in_array(mb_strtoupper($word"UTF-8"), $exceptions)) {
                        
    // check exceptions list for any words that should be in upper case
                        
    $word mb_strtoupper($word"UTF-8");
                    } elseif (
    in_array(mb_strtolower($word"UTF-8"), $exceptions)) {
                        
    // check exceptions list for any words that should be in upper case
                        
    $word mb_strtolower($word"UTF-8");
                    } elseif (!
    in_array($word$exceptions)) {
                        
    // convert to uppercase (non-utf8 only)
                        
    $word ucfirst($word);
                    }
                    
    array_push($newwords$word);
                }
                
    $string join($delimiter$newwords);
           }
    //foreach
           
    return $string;
        }

        
    $test "now for a test. [hd2]this is header2[/hd] test! does THIS [hd3] this is header3 [/hd]THING work? we will soon know # willl we not ? see you soon";
        
    $the_title "this-that is. a test of the Mcdougal title";

        
    $test_title_out titleCase($the_title);
        
    $test_output2 preg_replace_callback('/\[hd[1-6]\]([\w\W]*?)\[\/hd\]/''titleCase'$test);

        echo 
    "<br><br>Test_title_out<br>$test_title_out<br><br>";
        echo 
    "<br><br>Test_output 2<br>$test_output2<br><br>";

    ?>
    Output

    Test_title_out
    This-That Is. A Test of The McDougal Title

    Test_output 2
    now for a test. This Is Header2 test! does THIS This Is Header3 THING work? we will soon know # willl we not ? see you soon
    JavaScript: Learn | Validate | Compact | bionoid

  7. #7
    Join Date
    May 2006
    Posts
    245
    I just came back to write that I was correct to have the
    $string = $matches[1]; line in there otherwise
    the string wasn't getting defined.

    Now you have put a little if() stmt to check if $string is an array or not.

    OK - is that because if the Title only has ONE word it will not be an array ?
    BUT $newwords is defined as an array so can $string be anything other ?


    I understand the other stuff you corrected for me.
    Developers Choice Revealed:
    www.devchoice.info
    Which host has won, and why ?

  8. #8
    Join Date
    Dec 2011
    Location
    Centurion, South Africa
    Posts
    795
    Calling the function directly is typically done using a string, but when the preg_replace_callback calls it, it will pass an array.

    So checking if an array was passed will allow both methods to be used with only one function.
    JavaScript: Learn | Validate | Compact | bionoid

  9. #9
    Join Date
    May 2006
    Posts
    245
    OK - I see
    ( That's clever !! )

    BTW isn't this line redundant ??
    $string = mb_convert_case($string, MB_CASE_TITLE, "UTF-8");


    .
    Developers Choice Revealed:
    www.devchoice.info
    Which host has won, and why ?

  10. #10
    Join Date
    Dec 2011
    Location
    Centurion, South Africa
    Posts
    795
    I honestly didn't look into how you were case'ing the text. Do you really need to cater for characters out of the ASCII range? You know those mb_ functions are flipping slow :P
    JavaScript: Learn | Validate | Compact | bionoid

  11. #11
    Join Date
    May 2006
    Posts
    245
    Well, The text could have Turkish or German characters in it.

    But actually I can test for that because the document will be classified by language anyway.

    Assuming that it is English language then, what would be a may "economical" way to case it. ?

    and ...

    isn't this line redundant ??
    $string = mb_convert_case($string, MB_CASE_TITLE, "UTF-8");

    .
    Developers Choice Revealed:
    www.devchoice.info
    Which host has won, and why ?

  12. #12
    Join Date
    Dec 2011
    Location
    Centurion, South Africa
    Posts
    795
    It does seem a little pointless, this line seems to take care of it:

    PHP Code:
    $word ucfirst($word); 
    JavaScript: Learn | Validate | Compact | bionoid

  13. #13
    Join Date
    May 2006
    Posts
    245
    Yes,
    That's what I thought.

    So, I now have this, which for most cases will work a lot faster ??


    PHP Code:
    function titleCase($matches){
        
    $string is_array($matches) ? $matches[1] : $matches;
        
    $delimiters = array(" ""-"".""'""O'""Mc");
        
    $exceptions = array("and""to""of""das""dos""I""II""III""IV""V""VI");
        if(
    $lang_cd == 'En'){
          foreach (
    $delimiters as $dlnr => $delimiter) {
            
    $words explode($delimiter$string);
            
    $newwords = array();
            foreach (
    $words as $wordnr => $word) {
                if (
    in_array(strtoupper($word), $exceptions)) {
                    
    // check exceptions list for any words that should be in upper case
                    
    $word strtoupper($word);
                } elseif (
    in_array(strtolower($word), $exceptions)) {
                    
    // check exceptions list for any words that should be in upper case
                    
    $word strtolower($word);
                } elseif (!
    in_array($word$exceptions)) {
                    
    // convert to uppercase (non-utf8 only)
                    
    $word ucfirst($word);
                }
                
    array_push($newwords$word);
            }
            
    $string join($delimiter$newwords);
            }  
    //  end foreach
            
    return $string;
          }  
    // end if
        
    else {
          foreach (
    $delimiters as $dlnr => $delimiter) {
            
    $words explode($delimiter$string);
            
    $newwords = array();
            foreach (
    $words as $wordnr => $word) {
                if (
    in_array(mb_strtoupper($word"UTF-8"), $exceptions)) {
                    
    // check exceptions list for any words that should be in upper case
                    
    $word mb_strtoupper($word"UTF-8");
                } elseif (
    in_array(mb_strtolower($word"UTF-8"), $exceptions)) {
                    
    // check exceptions list for any words that should be in upper case
                    
    $word mb_strtolower($word"UTF-8");
                } elseif (!
    in_array($word$exceptions)) {
                    
    // convert to uppercase (non-utf8 only)
                    
    $word ucfirst($word);
                }
                
    array_push($newwords$word);
            }
            
    $string join($delimiter$newwords);
            }  
    //  end foreach
            
    return $string;
          }  
    // end else
        


    .
    Developers Choice Revealed:
    www.devchoice.info
    Which host has won, and why ?

  14. #14
    Join Date
    Dec 2011
    Location
    Centurion, South Africa
    Posts
    795
    Looks OK.

    Did you know you could set the encoding type for all the mb_ functions?

    PHP Code:
    mb_internal_encoding('UTF-8'); 
    Then you can just make calls like:

    PHP Code:
    mb_strtoupper($word
    JavaScript: Learn | Validate | Compact | bionoid

  15. #15
    Join Date
    May 2006
    Posts
    245
    Hmmm ... thanks.

    BTW ... How do I pass an extra parameter to the callback function ??

    E.G. I have:


    function titleCase($matches,$lang_cd){
    blah blah
    }



    and ...

    PHP Code:
    $test_output2 preg_replace_callback(
        
    '/\[hd[1-6]\](.+?)\[\/hd\]/',
        
    'titleCase',
        
    $test); 
    Where do I put the $lang_cd ?

    Thanks.


    Oh - and you may notice I still used my (.+?)
    what was the advantage of ([\w\W]*?) ??


    .
    Last edited by jeddik; 12-23-2013 at 02:24 PM.
    Developers Choice Revealed:
    www.devchoice.info
    Which host has won, and why ?

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center



Recent Articles