11
\$\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\$
  • 3
    \$\begingroup\$ What you describe is usually called PascalCase. \$\endgroup\$ – Nicolas Raoul Aug 9 '16 at 8:55
13
\$\begingroup\$

More effective solution:

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

From Gears library

\$\endgroup\$
  • 1
    \$\begingroup\$ Hi. Welcome to Code Review! Why is this solution more effective? \$\endgroup\$ – mdfst13 May 31 '16 at 15:23
  • \$\begingroup\$ Because, array_map is expensive operation \$\endgroup\$ – Cosmologist Jun 2 '16 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\$ – starbeamrainbowlabs Nov 8 '16 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 '17 at 3:28
  • \$\begingroup\$ @aokaddaoc, good solution! \$\endgroup\$ – Cosmologist Jul 14 '17 at 11:13
1
\$\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\$
1
\$\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\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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