2

I have a string: 'Some_string_to_capitalize' which I would like to transform to 'Some_String_To_Capitalize'. I have tried:

$result = preg_replace( '/(_([a-z]{1}))/' , strtoupper('$1') , $subject  )

and

$result = preg_replace( '/(_([a-z]{1}))/' , "strtoupper($1)" , $subject  )

I looked at the php man page and here on SO but found nothing. Apologies if this is a dup!

This is the equivalent SO question for Javascript.

Community
  • 1
  • 1
AndyPerlitch
  • 4,539
  • 5
  • 28
  • 43

4 Answers4

9

I think you want to use preg_replace_callback:

In PHP 5.3+

<?php
$subject = 'Some_string_to_capitalize';
$result = preg_replace_callback(
    '/(_([a-z]{1}))/',
    function ($matches) {
        return strtoupper($matches[0]);
    } ,
    $subject
);

For PHP below 5.3

function toUpper($matches) {
    return strtoupper($matches[0]);
}

$result = preg_replace_callback('/(_([a-z]{1}))/', 'toUpper', $subject);
Ismail El Moudni
  • 622
  • 2
  • 9
  • 19
David Stockton
  • 2,261
  • 1
  • 14
  • 20
  • 1
    +1 Howard answered first so i gave the accept to him but this was also an extremely informative answer. Thanks! – AndyPerlitch Mar 26 '12 at 20:09
  • 1
    It's not about who answers first, it's about whether the answer is good. The /e modifier is not a good idea. It can be dangerous, it is now deprecated and will be removed from PHP altogether at some point. – Josh Davis Mar 26 '12 at 21:06
  • @Josh Davis I did some googling and you are absolutely right about the safety concern. At the time that I accepted Howard's answer I didn't see any clear advantage between his and David's. Thanks for pointing that out. – AndyPerlitch Mar 29 '12 at 22:53
1

Try adding letter "e" (meaning eval) as modifier to your regular expression.

$result = preg_replace("/(_([a-z]{1}))/e" , "strtoupper(\\1)" , $subject);
Howard
  • 38,639
  • 9
  • 64
  • 83
  • Awesome. One thing you forgot was putting single quotes around \\1. Tried to edit and SO refused... tried to accept your answer and SO said I could after 4 minutes. Are these measures new? – AndyPerlitch Mar 26 '12 at 20:04
  • If you turn on notices without the quotes, you'll see that PHP is issuing notices for every time it runs across a match: Notice: Use of undefined constant _t - assumed '_t' .... – David Stockton Mar 26 '12 at 20:10
  • I believe David is correct. I was getting the same "undefined constant" message. The replacement part of your answer should be edited to `"strtoupper('\\1')"` – AndyPerlitch Mar 26 '12 at 20:46
  • Just as a side note, please take great care whenever you use the e regex modifier and a string from a user. It can be used to execute arbitrary commands. This means they can potentially access a database, delete files, etc, etc. It is much safer to use the preg_replace_callback function.... – Mattisdada Aug 12 '14 at 00:43
1

I think you want ucfirst not strtoupper. That will capitalize only the first letter of each match, not the entire match like strtoupper will. I'm also thinking you're going to need to switch to preg_replace_callback because your current syntax is telling php to run strtoupper on the string '$1' (which does nothing) and then pass that in as a replacement string to use for ALL matches made. Which would give you the exact same output as input.

Try this instead:

<?php
preg_replace_callback(
    '/(_([a-z]{1}))/',
    create_function(
        // single quotes are essential here,
        // or alternative escape all $ as \$
        '$matches',
        'return ucfirst($matches[0]);'
    ),
    $subject
);
?>
Brian
  • 3,013
  • 19
  • 27
1

You've got some good answers posted thus far; however, I thought I'd post a variation just for kicks:

[updated] edited code snipped to be more terse:

<?php

$string = 'Some_strIng_to_caPitÃliZe';
echo mb_convert_case($string, MB_CASE_TITLE, 'UTF-8');
// Some_String_To_Capitãlize

The above code considers the following:

  1. Unicode characters may be a part of the string; in which case, 'UTF-8' should be a safe encoding:

  2. mb_convert_case using the flag MB_CASE_TITLE takes care of words that come in with a mixed case, so we don't need to manually normalize and "_" is considered a word boundry.

  3. The mb_convert_case function works with PHP versions since 4.3.0

PHP Source for reference.

Wil Moore III
  • 6,968
  • 3
  • 36
  • 49