19
\$\begingroup\$

Is there an effective way, maybe with regex, to change the following text pattern?

I have a string like abc_def_ghi_jkl. I want to replace it to AbcDefGhiJkl. I currently use the following code to change it. Is there a more effective way than this?

implode('',array_map('ucfirst',explode('_',$string)));
\$\endgroup\$
1
  • 3
    \$\begingroup\$ What you describe is usually called PascalCase. \$\endgroup\$ Aug 9, 2016 at 8:55

3 Answers 3

26
\$\begingroup\$

More effective solution:

str_replace('_', '', ucwords($key, '_'));

From Gears library

\$\endgroup\$
5
  • 1
    \$\begingroup\$ Hi. Welcome to Code Review! Why is this solution more effective? \$\endgroup\$
    – mdfst13
    May 31, 2016 at 15:23
  • \$\begingroup\$ Because, array_map is expensive operation \$\endgroup\$ Jun 2, 2016 at 12:05
  • 1
    \$\begingroup\$ Here's a test that proves the above point: repl.it/ERrZ/6 (For the lazy: array_map: 575ms, str_replace: 365ms). Suggestion: Add more of an explanation next time :-) \$\endgroup\$ Nov 8, 2016 at 9:58
  • 1
    \$\begingroup\$ Why not str_replace('_', '', ucwords($key, '_'))? It is faster and code shorter by setting delimiter directly in ucwords \$\endgroup\$
    – tom10271
    Feb 23, 2017 at 3:28
  • \$\begingroup\$ @aokaddaoc, good solution! \$\endgroup\$ Jul 14, 2017 at 11:13
3
\$\begingroup\$

I know, its not the latest question, but here is another solution.

Not really pretty, but works well, is in one line and has a better performance than the solution in the question: str_replace(' ', '', ucwords(str_replace(['-', '_'], ' ', $str)))

BTW. here are some microtime results from my server:

// 9.0599060058594E-6
// 
$result = implode('',array_map('ucfirst',explode('_',$string)));

// 4.2915344238281E-5
// 
$result = preg_replace_callback("/(?:^|_)([a-z])/", function($matches) {
  return strtoupper($matches[1]);
}, $string);

// 5.0067901611328E-6
// 
$result = str_replace(' ', '', ucwords(str_replace(['-', '_'], ' ', $string)));
\$\endgroup\$
2
\$\begingroup\$

You could use preg_replace_callback(), which replaces matches with the result of a function:

$str = "abc_def_ghi_jkl";
$str = preg_replace_callback("/(?:^|_)([a-z])/", function($matches) {
//       Start or underscore    ^      ^ lowercase character
    return strtoupper($matches[1]);
}, $str);
echo $str;

Whichever works for you, your solution is fine as well.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.