How to convert PascalCase to pascal_case?

If I had:

$string = "PascalCase"; 

I need

 "pascal_case" 

Does PHP offer a function for this purpose?

+105
string php camelcasing pascalcasing
Jan 03 '09 at 2:20
source share
29 answers

Try this for size:

 $tests = array( 'simpleTest' => 'simple_test', 'easy' => 'easy', 'HTML' => 'html', 'simpleXML' => 'simple_xml', 'PDFLoad' => 'pdf_load', 'startMIDDLELast' => 'start_middle_last', 'AString' => 'a_string', 'Some4Numbers234' => 'some4_numbers234', 'TEST123String' => 'test123_string', ); foreach ($tests as $test => $result) { $output = from_camel_case($test); if ($output === $result) { echo "Pass: $test => $result\n"; } else { echo "Fail: $test => $result [$output]\n"; } } function from_camel_case($input) { preg_match_all('!([AZ][A-Z0-9]*(?=$|[AZ][a-z0-9])|[A-Za-z][a-z0-9]+)!', $input, $matches); $ret = $matches[0]; foreach ($ret as &$match) { $match = $match == strtoupper($match) ? strtolower($match) : lcfirst($match); } return implode('_', $ret); } 

Output:

 Pass: simpleTest => simple_test Pass: easy => easy Pass: HTML => html Pass: simpleXML => simple_xml Pass: PDFLoad => pdf_load Pass: startMIDDLELast => start_middle_last Pass: AString => a_string Pass: Some4Numbers234 => some4_numbers234 Pass: TEST123String => test123_string 

This implements the following rules:

  • After a sequence starting with a lowercase letter, lowercase letters and numbers should follow;
  • A sequence starting with a capital letter may be followed by:
    • one or more capital letters and numbers (followed by either the end of a line or an upper case letter, followed by a lower case letter or number, i.e. the beginning of the next sequence); or
    • one or more lowercase letters or numbers.
+150
Jan 03 '09 at 2:45
source share

A shorter solution: similar to an editor with simplified regular expression and fixing the "trailing-underscore" problem:

 $output = strtolower(preg_replace('/(?<!^)[AZ]/', '_$0', $input)); 

PHP demo | Regex Demo




Please note that cases like SimpleXML will be converted to simple_x_m_l using the above solution. It can also be considered an incorrect use of camel notation (the correct one would be SimpleXML ), and not an algorithm error, since such cases are always ambiguous - even by grouping uppercase characters on one line ( simple_xml ), such an algorithm will always fail in other cases, such as XMLHTMLConverter or single-letter words close to abbreviations, etc. If you don't mind (fairly rare) edge cases and want to handle SimpleXML , you can use a slightly more complex solution:

 $output = ltrim(strtolower(preg_replace('/[AZ]([AZ](?![az]))*/', '_$0', $input)), '_'); 

PHP demo | Regex Demo

+135
Oct 23 '13 at 5:08 on
source share

A concise solution and can handle some complex use cases:

 function decamelize($string) { return strtolower(preg_replace(['/([az\d])([AZ])/', '/([^_])([AZ][az])/'], '$1_$2', $string)); } 

It can handle all of these cases:

 simpleTest => simple_test easy => easy HTML => html simpleXML => simple_xml PDFLoad => pdf_load startMIDDLELast => start_middle_last AString => a_string Some4Numbers234 => some4_numbers234 TEST123String => test123_string hello_world => hello_world hello__world => hello__world _hello_world_ => _hello_world_ hello_World => hello_world HelloWorld => hello_world helloWorldFoo => hello_world_foo hello-world => hello-world myHTMLFiLe => my_html_fi_le aBaBaB => a_ba_ba_b BaBaBa => ba_ba_ba libC => lib_c 

You can check this feature here: http://syframework.alwaysdata.net/decamelize

+32
Mar 01 '16 at 9:54 on
source share

Ported from Ruby String#camelize and String#decamelize .

 function decamelize($word) { return preg_replace( '/(^|[az])([AZ])/e', 'strtolower(strlen("\\1") ? "\\1_\\2" : "\\2")', $word ); } function camelize($word) { return preg_replace('/(^|_)([az])/e', 'strtoupper("\\2")', $word); } 

One trick I might have skipped above is the 'e' modifier, which causes preg_replace evaluate the replacement string as PHP code.

+24
Mar 04 '11 at 13:40
source share

The Symfony Serializer component has a CamelCaseToSnakeCaseNameConverter , which has two methods, normalize() and denormalize() . They can be used as follows:

 $nameConverter = new CamelCaseToSnakeCaseNameConverter(); echo $nameConverter->normalize('camelCase'); // outputs: camel_case echo $nameConverter->denormalize('snake_case'); // outputs: snakeCase 
+21
Jun 17 '16 at 12:23
source share

Most decisions here are hard. Here is what I use:

 $underscored = strtolower( preg_replace( ["/([AZ]+)/", "/_([AZ]+)([AZ][az])/"], ["_$1", "_$1_$2"], lcfirst($camelCase) ) ); 

"CamelCASE" is converted to "camel_case"

  • lcfirst($camelCase) first character (avoids the converted CamelCASE output to start with an underscore)
  • [AZ] finds capital letters
  • + will treat every next uppercase character as a word (avoids "CamelCASE" to convert to camel_C_A_S_E)
  • Second template and replacement for ThoseSPECCases - ThoseSPECCases those_spec_cases instead of those_speccases
  • strtolower([…]) turns output into lower regions
+20
May 01 '13 at 13:48
source share

php does not offer a built-in function for this afaik, but here is what I use

 function uncamelize($camel,$splitter="_") { $camel=preg_replace('/(?!^)[[:upper:]][[:lower:]]/', '$0', preg_replace('/(?!^)[[:upper:]]+/', $splitter.'$0', $camel)); return strtolower($camel); } 

a splitter can be specified in a function call, so you can call it like this

 $camelized="thisStringIsCamelized"; echo uncamelize($camelized,"_"); //echoes "this_string_is_camelized" echo uncamelize($camelized,"-"); //echoes "this-string-is-camelized" 
+17
Jan 03 '09 at 2:27
source share
 header('content-type: text/html; charset=utf-8'); $separated = preg_replace('%(?<!^)\p{Lu}%usD', '_$0', 'AaaaBbbbCcccDdddÁáááŐőőő'); $lower = mb_strtolower($separated, 'utf-8'); echo $lower; //aaaa_bbbb_cccc_dddd_áááá_őőőő 
+8
May 23 '12 at 19:45
source share

If you are looking for PHP version 5.4 and a later answer, here is the code:

 function decamelize($word) { return $word = preg_replace_callback( "/(^|[az])([AZ])/", function($m) { return strtolower(strlen($m[1]) ? "$m[1]_$m[2]" : "$m[2]"); }, $word ); } function camelize($word) { return $word = preg_replace_callback( "/(^|_)([az])/", function($m) { return strtoupper("$m[2]"); }, $word ); } 
+6
Feb 25 '15 at 23:20
source share

I do not like it at all, but simply and quickly, like hell:

 function uncamelize($str) { $str = lcfirst($str); $lc = strtolower($str); $result = ''; $length = strlen($str); for ($i = 0; $i < $length; $i++) { $result .= ($str[$i] == $lc[$i] ? '' : '_') . $lc[$i]; } return $result; } echo uncamelize('HelloAWorld'); //hello_a_world 
+4
Dec 16 '13 at 17:36
source share

"CamelCase" on "camel_case":

 function camelToSnake($camel) { $snake = preg_replace('/[AZ]/', '_$0', $camel); $snake = strtolower($snake); $snake = ltrim($snake, '_'); return $snake; } 

or

 function camelToSnake($camel) { $snake = preg_replace_callback('/[AZ]/', function ($match){ return '_' . strtolower($match[0]); }, $camel); return ltrim($snake, '_'); } 
+4
Dec 05 '17 at 2:03
source share

A non-regex version is found in Alchitect :

 decamelize($str, $glue='_') { $counter = 0; $uc_chars = ''; $new_str = array(); $str_len = strlen($str); for ($x=0; $x<$str_len; ++$x) { $ascii_val = ord($str[$x]); if ($ascii_val >= 65 && $ascii_val <= 90) { $uc_chars .= $str[$x]; } } $tok = strtok($str, $uc_chars); while ($tok !== false) { $new_char = chr(ord($uc_chars[$counter]) + 32); $new_str[] = $new_char . $tok; $tok = strtok($uc_chars); ++$counter; } return implode($new_str, $glue); } 
+3
Jan 03 '09 at 3:58
source share

So here is a single line:

 strtolower(preg_replace('/(?|([az\d])([AZ])|([^\^])([AZ][az]))/', '$1_$2', $string)); 
+3
Sep 17 '14 at 17:33
source share

danielstjules / Stringy confirms the method for converting a string from camelcase to snakecase.

 s('TestUCase')->underscored(); // 'test_u_case' 
+3
Nov 29 '16 at 12:35
source share

Laravel 5.6 provides a very easy way to do this:

  /** * Convert a string to snake case. * * @param string $value * @param string $delimiter * @return string */ public static function snake($value, $delimiter = '_'): string { if (!ctype_lower($value)) { $value = strtolower(preg_replace('/(.)(?=[AZ])/u', '$1'.$delimiter, $value)); } return $value; } 

What he does: if he sees that there is at least one uppercase letter in a given line, he uses a positive forecast to search for any character ( . ) Followed by a capital letter ( (?=[AZ]) ). Then it replaces the found character with its value, followed by the separator _ .

+3
Jun 27 '18 at 11:27
source share

A direct port from the rails (minus their special processing for :: or acronyms) will be

 function underscore($word){ $word = preg_replace('#([AZ\d]+)([AZ][az])#','\1_\2', $word); $word = preg_replace('#([az\d])([AZ])#', '\1_\2', $word); return strtolower(strtr($word, '-', '_')); } 

Knowing PHP, this will be faster than the manual parsing that occurs in the other answers given here. The disadvantage is that you cannot choose what to use as a separator between words, but that was not part of the question.

Also check the appropriate rails source code

Please note that this is for use with ASCII identifiers. If you need to do this with characters outside the ASCII range, use the '/ u' modifier for preg_match and use mb_strtolower .

+2
Oct. 23 '13 at 19:43
source share

Here is my contribution to the six-year question when God knows how many answers ...

It converts all the words in the provided string that are in the camelcase to snakecase. For example, "SuperSpecialAwesome, as well as FizBuzz καιΚάτιΑκόμα" will be converted to "super_special_awesome, as well as fizz_buzz και_κάτι_ακόμα."

 mb_strtolower( preg_replace_callback( '/(?<!\b|_)\p{Lu}/u', function ($a) { return "_$a[0]"; }, 'SuperSpecialAwesome' ) ); 
+2
Dec 28 '16 at 15:17
source share

Yii2 has another function for creating the word snake_case from CamelCase.

  /** * Converts any "CamelCased" into an "underscored_word". * @param string $words the word(s) to underscore * @return string */ public static function underscore($words) { return strtolower(preg_replace('/(?<=\\w)([AZ])/', '_\\1', $words)); } 
+2
Aug 22 '18 at 7:14
source share

How to remove a camel without using regular expressions:

 function decamelize($str, $glue = '_') { $capitals = []; $replace = []; foreach(str_split($str) as $index => $char) { if(!ctype_upper($char)) { continue; } $capitals[] = $char; $replace[] = ($index > 0 ? $glue : '') . strtolower($char); } if(count($capitals) > 0) { return str_replace($capitals, $replace, $str); } return $str; } 

Editing:

How would I do it in 2019:

 function toSnakeCase($str, $glue = '_') { return preg_replace_callback('/[AZ]/', function ($matches) use ($glue) { return $glue . strtolower($matches[0]); }, $str); } 

And when PHP 7.4 comes out:

 function toSnakeCase($str, $glue = '_') { return preg_replace_callback('/[AZ]/', fn($matches) => $glue . strtolower($matches[0]), $str); } 
+1
Apr 09 '13 at 12:30
source share
 function camel2snake($name) { $str_arr = str_split($name); foreach ($str_arr as $k => &$v) { if (ord($v) >= 64 && ord($v) <= 90) { // A = 64; Z = 90 $v = strtolower($v); $v = ($k != 0) ? '_'.$v : $v; } } return implode('', $str_arr); } 
+1
Dec 05 '13 at 5:01
source share

There is a library that provides this functionality:

 SnakeCaseFormatter::run('CamelCase'); // Output: "camel_case" 
+1
Apr 02 '16 at 1:04 on
source share

If you use a Laravel frame, you can use the snake_case () method.

+1
Nov 11 '16 at 16:25
source share
 $str = 'FooBarBaz'; return strtolower(preg_replace('~(?<=\\w)([AZ])~', '_$1', $str)); // foo_bar_baz 
+1
Oct 25 '17 at 9:39 on
source share

This is one of the short ways:

 function camel_to_snake($input) { return strtolower(ltrim(preg_replace('/([AZ])/', '_\\1', $input), '_')); } 
+1
Feb 15 '19 at 13:12
source share

Short decision:

 $subject = "PascalCase"; echo strtolower(preg_replace('/\B([AZ])/', '_$1', $subject)); 
+1
Jun 12 '19 at 11:01
source share

It is easy to use the Zend Word Filters filter classes:

 <?php namespace MyNamespace\Utility; use Zend\Filter\Word\CamelCaseToUnderscore; use Zend\Filter\Word\UnderscoreToCamelCase; class String { public function test() { $underscoredStrings = array( 'simple_test', 'easy', 'html', 'simple_xml', 'pdf_load', 'start_middle_last', 'a_string', 'some4_numbers234', 'test123_string', ); $camelCasedStrings = array( 'simpleTest', 'easy', 'HTML', 'simpleXML', 'PDFLoad', 'startMIDDLELast', 'AString', 'Some4Numbers234', 'TEST123String', ); echo PHP_EOL . '-----' . 'underscoreToCamelCase' . '-----' . PHP_EOL; foreach ($underscoredStrings as $rawString) { $filteredString = $this->underscoreToCamelCase($rawString); echo PHP_EOL . $rawString . ' >>> ' . $filteredString . PHP_EOL; } echo PHP_EOL . '-----' . 'camelCaseToUnderscore' . '-----' . PHP_EOL; foreach ($camelCasedStrings as $rawString) { $filteredString = $this->camelCaseToUnderscore($rawString); echo PHP_EOL . $rawString . ' >>> ' . $filteredString . PHP_EOL; } } public function camelCaseToUnderscore($input) { $camelCaseToSeparatorFilter = new CamelCaseToUnderscore(); $result = $camelCaseToSeparatorFilter->filter($input); $result = strtolower($result); return $result; } public function underscoreToCamelCase($input) { $underscoreToCamelCaseFilter = new UnderscoreToCamelCase(); $result = $underscoreToCamelCaseFilter->filter($input); return $result; } } 

----- underscoreToCamelCase -----

simple_test →> SimpleTest

easy →> easy

html →> Html

simple_xml →> SimpleXml

pdf_load →> PdfLoad

start_middle_last →> StartMiddleLast

a_string →> AString

some4_numbers234 →> Some4Numbers234

test123_string →> Test123String

----- camelCaseToUnderscore -----

simpleTest →> simple_test

easy →> easy

HTML →> html

simpleXML →> simple_xml

PDFLoad →> pdf_load

startMIDDLELast →> start_middle_last

AString →> a_string

Some4Numbers234 →> some4_numbers234

TEST123String →> test123_string

0
Dec 16 '13 at 17:02
source share

The worst answer here was so close to being the best (use the framework). NO NO, just take a look at the source code. seeing that it uses a well-established framework will be a much more reliable approach (tried and tested). Zend has word filters that fit your needs. Source

Here are some methods that I adapted from the source.

 function CamelCaseToSeparator($value,$separator = ' ') { if (!is_scalar($value) && !is_array($value)) { return $value; } if (defined('PREG_BAD_UTF8_OFFSET_ERROR') && preg_match('/\pL/u', 'a') == 1) { $pattern = ['#(?<=(?:\p{Lu}))(\p{Lu}\p{Ll})#', '#(?<=(?:\p{Ll}|\p{Nd}))(\p{Lu})#']; $replacement = [$separator . '\1', $separator . '\1']; } else { $pattern = ['#(?<=(?:[AZ]))([AZ]+)([AZ][az])#', '#(?<=(?:[a-z0-9]))([AZ])#']; $replacement = ['\1' . $separator . '\2', $separator . '\1']; } return preg_replace($pattern, $replacement, $value); } function CamelCaseToUnderscore($value){ return CamelCaseToSeparator($value,'_'); } function CamelCaseToDash($value){ return CamelCaseToSeparator($value,'-'); } $string = CamelCaseToUnderscore("CamelCase"); 
0
Nov 09 '15 at 9:36
source share

The TurboCommons open source library contains a general-purpose formatCase () method inside the StringUtils class that allows you to convert a string to many common case formats, such as CamelCase, UpperCamelCase, LowerCamelCase, snake_case, Title Case, and many others.

https://github.com/edertone/TurboCommons

To use it, import the phar file into your project and:

 use org\turbocommons\src\main\php\utils\StringUtils; echo StringUtils::formatCase('camelCase', StringUtils::FORMAT_SNAKE_CASE); // will output 'camel_Case' 
0
Mar 10 '17 at 23:22
source share

IF you can start with:

 $string = 'Camel_Case'; // underscore or any other separator... 

Then you can convert to any of these:

 $pascal = str_replace("_", "", $string); $snake = strtolower($string); 

Or any other cases:

 $capitalized = str_replace("_", " ", $string); // Camel Case $constant = strtoupper($string); // CAMEL_CASE $train = str_replace("_", "-", $snake); // camel-case 
-one
Mar 28 '15 at 15:40
source share



All Articles