How to convert PascalCase to pascal_case?

前端 未结 30 1444
北海茫月
北海茫月 2020-11-29 16:36

If I had:

$string = \"PascalCase\";

I need

\"pascal_case\"

Does PHP offer a function for this purpose?

相关标签:
30条回答
  • 2020-11-29 17:25

    A shorter solution: Similar to the editor's one with a simplified regular expression and fixing the "trailing-underscore" problem:

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

    PHP Demo | Regex Demo


    Note that cases like SimpleXML will be converted to simple_x_m_l using the above solution. That can also be considered a wrong usage of camel case notation (correct would be SimpleXml) rather than a bug of the algorithm since such cases are always ambiguous - even by grouping uppercase characters to one string (simple_xml) such algorithm will always fail in other edge cases like XMLHTMLConverter or one-letter words near abbreviations, etc. If you don't mind about the (rather rare) edge cases and want to handle SimpleXML correctly, you can use a little more complex solution:

    $output = ltrim(strtolower(preg_replace('/[A-Z]([A-Z](?![a-z]))*/', '_$0', $input)), '_');
    

    PHP Demo | Regex Demo

    0 讨论(0)
  • 2020-11-29 17:27

    There is a library providing this functionality:

    SnakeCaseFormatter::run('CamelCase'); // Output: "camel_case"
    
    0 讨论(0)
  • 2020-11-29 17:28

    I had a similar problem but couldn't find any answer that satisfies how to convert CamelCase to snake_case, while avoiding duplicate or redundant underscores _ for names with underscores, or all caps abbreviations.

    Th problem is as follows:

    CamelCaseClass            => camel_case_class
    ClassName_WithUnderscores => class_name_with_underscore
    FAQ                       => faq
    

    The solution I wrote is a simple two functions call, lowercase and search and replace for consecutive lowercase-uppercase letters:

    strtolower(preg_replace("/([a-z])([A-Z])/", "$1_$2", $name));
    
    0 讨论(0)
  • 2020-11-29 17:30

    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);
    
    }
    

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

    $camelized="thisStringIsCamelized";
    echo uncamelize($camelized,"_");
    //echoes "this_string_is_camelized"
    echo uncamelize($camelized,"-");
    //echoes "this-string-is-camelized"
    
    0 讨论(0)
  • 2020-11-29 17:30

    You need to run a regex through it that matches every uppercase letter except if it is in the beginning and replace it with underscrore plus that letter. An utf-8 solution is this:

    header('content-type: text/html; charset=utf-8');
    $separated = preg_replace('%(?<!^)\p{Lu}%usD', '_$0', 'AaaaBbbbCcccDffffdÁáááŐőőő');
    $lower = mb_strtolower($separated, 'utf-8');
    echo $lower; //aaaa_bbbb_cccc_ffffdd_áááá_őőőő
    

    If you are not sure what case your string is, better to check it first, because this code assumes that the input is camelCase instead of underscore_Case or dash-Case, so if the latters have uppercase letters, it will add underscores to them.

    The accepted answer from cletus is way too overcomplicated imho and it works only with latin characters. I find it a really bad solution and wonder why it was accepted at all. Converting TEST123String into test123_string is not necessarily a valid requirement. I rather kept it simple and separated ABCccc into a_b_cccc instead of ab_cccc because it does not lose information this way and the backward conversion will give the exact same string we started with. Even if you want to do it the other way it is relative easy to write a regex for it with positive lookbehind (?<!^)\p{Lu}\p{Ll}|(?<=\p{Ll})\p{Lu} or two regexes without lookbehind if you are not a regex expert. There is no need to split it up into substrings not to mention deciding between strtolower and lcfirst where using just strtolower would be completely fine.

    0 讨论(0)
  • 2020-11-29 17:30

    It's easy using the Filter classes of the Zend Word Filters:

    <?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 讨论(0)
提交回复
热议问题