【问题标题】:How to convert PascalCase to snake_case?如何将 PascalCase 转换为 snake_case?
【发布时间】:2010-01-03 02:20:51
【问题描述】:

如果我有:

$string = "PascalCase";

我需要

"pascal_case"

PHP 是否为此提供了函数?

【问题讨论】:

  • 从技术上讲,第一个示例字符串是 PascalCase。
  • 第二个示例字符串被称为snake_case
  • 我知道这已经晚了 8 年,但只是想指出 OP 清楚地键入了“pascal_case”而不是“snake_case”,因为它是将字符串“PascalCase”转换为蛇形大小写,而不是字符串“snake_case”。

标签: php string pascalcasing snakecasing


【解决方案1】:

一个更短的解决方案:类似于编辑器的一个简化的正则表达式并修复“尾随下划线”问题:

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

PHP Demo | Regex Demo


请注意,SimpleXML 之类的情况将使用上述解决方案转换为 simple_x_m_l。这也可以被认为是骆驼大小写表示法的错误使用(正确的是SimpleXml)而不是算法的错误,因为这种情况总是模棱两可的——即使通过将大写字符分组到一个字符串(simple_xml)这样的算法也会在其他边缘情况下总是失败,例如XMLHTMLConverter 或缩写附近的单字母单词等。如果您不介意(相当罕见的)边缘情况并希望正确处理SimpleXML,您可以使用更复杂一点解决方案:

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

PHP Demo | Regex Demo

【讨论】:

  • 欢迎评论 cletus 的回答,详细说明您修复了哪些测试用例。
  • 我并不是说他的解决方案给出了错误的结果。他的解决方案极其复杂且无效。
  • 是的,接受的答案肯定是失败的。 Jan的解决方案太棒了!附带说明一下,我认为这是我对 PHP 开发人员最喜欢的新的、最喜欢的编码测试,因为为这个问题提供的实际上不起作用的答案数量令人难以置信。这将是进行初始过滤的好方法。 :-)
  • 发现此解决方案中使用的正则表达式更加完整:stackoverflow.com/questions/2559759/…
  • 简单用例的好解决方案,在大多数常见情况下就足够了,但公认的解决方案可以处理更多用例,例如“simpleXML”可以转换为“simple_xml”而不是“simple_x_m_l”跨度>
【解决方案2】:

试穿一下尺寸:

$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('!([A-Z][A-Z0-9]*(?=$|[A-Z][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);
}

输出:

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

这实现了以下规则:

  1. 以小写字母开头的序列后面必须跟小写字母和数字;
  2. 以大写字母开头的序列可以后跟:
    • 一个或多个大写字母和数字(后跟字符串结尾或大写字母后跟小写字母或数字,即下一个序列的开始);或
    • 一个或多个小写字母或数字。

【讨论】:

  • 它适用于 CamelCased 字符串(如 openfrog 所要求的),但如果您将它与输入字符串一起使用,例如“r_id”(已经“下划线”),它会修剪前缀(“r_”)。很好的解决方案,但绝对不是通用的。
  • 好奇为什么要检查字符串是否与全大写字符串匹配?仅将第一个字符转换为小写(而不是所有字符)有什么好处?
  • 一个更简洁的解决方案,也可以处理所有这些用例:stackoverflow.com/a/35719689/4328383
【解决方案3】:

简洁的解决方案,可以处理一些棘手的用例:

function decamelize($string) {
    return strtolower(preg_replace(['/([a-z\d])([A-Z])/', '/([^_])([A-Z][a-z])/'], '$1_$2', $string));
}

可以处理所有这些情况:

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

你可以在这里测试这个功能:http://syframework.alwaysdata.net/decamelize

【讨论】:

  • @VivekVardhan 这个正则表达式的哪一部分你不明白?
  • 嗯,我认为小写非驼峰字符串是一种副作用,如果字符串不是驼峰格式,则应返回原始字符串。事实上,如果你发送'simple_Text',你会得到失败:simple_Test => simple_Test [simple_test]。只有当原始字符串是真正的驼峰式字符串时,才应制作小写字符串。你怎么看?
【解决方案4】:

Symfony Serializer Component 有一个CamelCaseToSnakeCaseNameConverter,它有两个方法normalize()denormalize()。这些可以按如下方式使用:

$nameConverter = new CamelCaseToSnakeCaseNameConverter();

echo $nameConverter->normalize('camelCase');
// outputs: camel_case

echo $nameConverter->denormalize('snake_case');
// outputs: snakeCase

【讨论】:

  • 当心! $nameConverter-&gt;normalize('CamelCase') 在 Symfony 串行器组件的当前版本 3.2 中输出 _camel_case
【解决方案5】:

移植自 Ruby 的 String#camelizeString#decamelize

function decamelize($word) {
  return preg_replace(
    '/(^|[a-z])([A-Z])/e', 
    'strtolower(strlen("\\1") ? "\\1_\\2" : "\\2")',
    $word 
  ); 
}

function camelize($word) { 
  return preg_replace('/(^|_)([a-z])/e', 'strtoupper("\\2")', $word); 
}

上述解决方案可能遗漏的一个技巧是“e”修饰符,它导致preg_replace 将替换字符串评估为 PHP 代码。

【讨论】:

【解决方案6】:

这里的大多数解决方案都让人感到手忙脚乱。这是我使用的:

$underscored = strtolower(
    preg_replace(
        ["/([A-Z]+)/", "/_([A-Z]+)([A-Z][a-z])/"], 
        ["_$1", "_$1_$2"], 
        lcfirst($camelCase)
    )
);

“CamelCASE”转换为“camel_case”

  • lcfirst($camelCase) 将降低第一个字符(避免 'CamelCASE' 转换后的输出以下划线开头)
  • [A-Z] 查找大写字母
  • + 会将每个连续的大写字母视为一个单词(避免将 'CamelCASE' 转换为 camel_C_A_S_E)
  • 第二个模式和替换是ThoseSPECCases -> those_spec_cases 而不是those_speccases
  • strtolower([…]) 将输出转为小写

【讨论】:

  • 但它也会将 CamelCased 转换为 _camel_cased。
  • 这很棒 - 只需添加一个从 char 1 开始的 substr 即可解决该问题。
  • 太棒了!只需将lcfirst 函数添加到$camelCase
  • 接受的答案将处理:TestUPSClass 变为 test_ups_class 而这会将其变为 test_u_p_s_class,请记住这一点。
  • 由于ucfirst() 调用,此解决方案会意外拆分以全大写第一个“单词”开头的输入字符串。 USADollarSymbol 变为 u_sa_dollar_symbol Demo 我不推荐这种解决方案,因为它必须使用正则表达式两次通过输入字符串——这是未优化模式的标志。
【解决方案7】:

php 没有为此 afaik 提供内置函数,但这是我使用的

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

}

分割器可以在函数调用中指定,所以可以这样调用

$camelized="thisStringIsCamelized";
echo uncamelize($camelized,"_");
//echoes "this_string_is_camelized"
echo uncamelize($camelized,"-");
//echoes "this-string-is-camelized"

【讨论】:

  • “ThisIsATest”失败。好像不支持两个连续的大写。
  • 你肯定忘记了什么,因为第二个替换什么也没做。除此之外,您可以轻松地使其 unicode 与 mb_strtolowerpreg_replace 上的 /u 选项兼容。
【解决方案8】:

“CamelCase”到“camel_case”:

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

或:

function camelToSnake($camel)
{
    $snake = preg_replace_callback('/[A-Z]/', function ($match){
        return '_' . strtolower($match[0]);
    }, $camel);
    return ltrim($snake, '_');
}

【讨论】:

  • 谢谢。我使用第一种方法,但使用连字符生成this-kind-of-output
【解决方案9】:

您需要通过它运行一个匹配每个大写字母的正则表达式,除非它在开头,并将其替换为下划线加上该字母。一个 utf-8 的解决方案是这样的:

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_áááá_őőőő

如果你不确定你的字符串是什么大小写,最好先检查一下,因为这段代码假设输入是camelCase而不是underscore_Casedash-Case,所以如果后者有大写字母,它将为它们添加下划线。

从 cletus 接受的答案太复杂了恕我直言,它只适用于拉丁字符。我发现这是一个非常糟糕的解决方案,并且想知道为什么它被接受了。将TEST123String 转换为test123_string 不一定是有效要求。我宁愿保持简单,并将ABCccc 分隔为a_b_cccc 而不是ab_cccc,因为它不会以这种方式丢失信息,并且反向转换将给出与我们开始时完全相同的字符串。即使您想以另一种方式执行此操作,如果您不是正则表达式专家,也可以相对容易地为它编写一个正则表达式(?&lt;!^)\p{Lu}\p{Ll}|(?&lt;=\p{Ll})\p{Lu} 或两个没有后视的正则表达式。无需将其拆分为子字符串,更不用说在 strtolowerlcfirst 之间选择仅使用 strtolower 就可以了。

【讨论】:

  • 纯代码答案在 Stackoverflow 上的价值很低,因为它们对教育/授权成千上万的未来研究人员几乎没有作用。
  • @mickmackusa 如果研究人员从 SO 中学习如何编码,那么我们就有一个严重的问题......
  • 既然您已经从系统中获得了人身攻击,请改进您的答案。假设您知道您的解决方案是如何工作的以及为什么要使用这些模式修饰符,我认为没有充分的理由向这个社区隐瞒知识。如果您正在考虑留下更多刻薄的回复,我向您保证他们不会打扰我。在您发表评论的时间里,您本可以完成您的回答,我们本可以删除我们的 cmets,而我本可以去其他地方帮助这个网站。
  • 当然,我没有权限删除一个有 8 个赞的帖子。如果您愿意,您可以删除您的答案,但通过删除不必要的模式修饰符并添加解释来简单地改进它并不难。人身攻击对我没有影响。
  • @mickmackusa 我想我也不能删除它。如果您愿意,请随意编辑。
【解决方案10】:

如果您正在寻找一个 PHP 5.4 版本和更高版本的答案是代码:

function decamelize($word) {
      return $word = preg_replace_callback(
        "/(^|[a-z])([A-Z])/",
        function($m) { return strtolower(strlen($m[1]) ? "$m[1]_$m[2]" : "$m[2]"); },
        $word
    );

}
function camelize($word) {
    return $word = preg_replace_callback(
        "/(^|_)([a-z])/",
        function($m) { return strtoupper("$m[2]"); },
        $word
    );

} 

【讨论】:

  • camelize 为 sms_sent 生成“SmsSent”,你需要一个 lcfirst
【解决方案11】:

我遇到了类似的问题,但找不到任何满足如何将 CamelCase 转换为 snake_case 的答案,同时避免重复或多余的下划线 _ 用于带有下划线或全部大写缩写的名称。

问题如下:

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

我写的解决方案是一个简单的两个函数调用,小写和搜索替换连续的小写-大写字母:

strtolower(preg_replace("/([a-z])([A-Z])/", "$1_$2", $name));

【讨论】:

  • 到目前为止,这是 IMO 最简洁和有用的解决方案。
【解决方案12】:

短解:

$subject = "PascalCase";
echo strtolower(preg_replace('/\B([A-Z])/', '_$1', $subject));

【讨论】:

    【解决方案13】:

    一点都不花哨,但简单快捷:

    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
    

    【讨论】:

    • ++$i 而不是 $i++ 也会让它更快一点;)
    • 纯代码答案在 Stackoverflow 上的价值很低,因为它们对教育/授权成千上万的未来研究人员几乎没有作用。
    【解决方案14】:

    不使用正则表达式的版本可以在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);
    }
    

    【讨论】:

    • 这就是没有正则表达式的生活:-)
    • 嘿,是的。 RegEx 绝对有它的优势。 :) 原始速度不是其中之一。
    • 由于某种原因得到了一些有趣的结果
    • 根据这个字符串对我不起作用:“CamelCaseTestAAATestAA”,应该有:“camel_case_test_a_a_a_test_a_a”,有:“”camel_case_test_aest”...
    【解决方案15】:

    所以这是一个单行:

    strtolower(preg_replace('/(?|([a-z\d])([A-Z])|([^\^])([A-Z][a-z]))/', '$1_$2', $string));
    

    【讨论】:

    • 很好,但它只转换第一次出现,所以我建议在这个正则表达式中添加一个g 修饰符。
    • @acme,我在没有g 的情况下使用它,它对我来说很好。
    • 出于某种原因,我不得不添加g。但我不记得我测试过的短语了。
    【解决方案16】:

    danielstjules/Stringy 提供了一种将字符串从驼峰式转换为蛇形的方法。

    s('TestUCase')->underscored(); // 'test_u_case'
    

    【讨论】:

      【解决方案17】:

      Laravel 5.6 提供了一种非常简单的方法:

       /**
       * 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('/(.)(?=[A-Z])/u', '$1'.$delimiter, $value));
          }
      
          return $value;
      }
      

      它的作用:如果它发现给定字符串中至少有一个大写字母,它使用positive lookahead 来搜索任何字符(.),然后是一个大写字母((?=[A-Z]))。然后它用它的值替换找到的字符,后跟分隔符_

      【讨论】:

      • 这个函数现在似乎被称为snake_case() 并且存在于全局命名空间中。
      【解决方案18】:

      来自 rails 的直接端口(减去它们对 :: 或首字母缩略词的特殊处理)将是

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

      了解 PHP,这将比此处给出的其他答案中发生的手动解析更快。缺点是您无法选择使用什么作为单词之间的分隔符,但这不是问题的一部分。

      同时检查relevant rails source code

      请注意,这适用于 ASCII 标识符。如果您需要对 ASCII 范围之外的字符执行此操作,请对 preg_match 使用“/u”修饰符并使用 mb_strtolower

      【讨论】:

      • 你可以,如果你简单地添加一个包含所需字符的参数。
      【解决方案19】:

      这是我对一个六年前的问题的贡献,天知道有多少答案......

      它会将提供的字符串中所有以驼峰命名的单词转换为蛇形。例如“SuperSpecialAwesome and also FizBuzz καιΚάτιΑκόμα”将被转换为“super_special_awesome and also fizz_buzz και_κάτι_ακόμα”。

      mb_strtolower(
          preg_replace_callback(
              '/(?<!\b|_)\p{Lu}/u',
              function ($a) {
                  return "_$a[0]";
              },
              'SuperSpecialAwesome'
          )
      );
      

      【讨论】:

        【解决方案20】:

        Yii2 具有从 CamelCase 制作单词 snake_case 的不同功能。

            /**
             * 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)([A-Z])/', '_\\1', $words));
            }
        

        【讨论】:

          【解决方案21】:

          如果您没有使用 Composer for PHP,那么您就是在浪费时间。

          composer require doctrine/inflector
          
          use Doctrine\Inflector\InflectorFactory;
          
          // Couple ways to get class name:
          
          // If inside a parent class
          $class_name = get_called_class();
          
          // Or just inside the class
          $class_name = get_class();
          
          // Or straight get a class name
          $class_name = MyCustomClass::class;
          
          // Or, of course, a string
          $class_name = 'App\Libs\MyCustomClass';
          
          // Take the name down to the base name:
          $class_name = end(explode('\\', $class_name)));
          
          $inflector = InflectorFactory::create()->build();
          
          $inflector->tableize($class_name); // my_custom_class
          

          https://github.com/doctrine/inflector/blob/master/docs/en/index.rst

          【讨论】:

            【解决方案22】:
            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);
            }
            

            【讨论】:

            • 您可以使用$name{$k}(或$name[$k])直接访问字符,这将使您的代码更长,但避免了将其与数组转换的巨大开销。
            • 纯代码答案在 StackOverflow 上的价值很低,因为它们在授权/教育未来研究人员方面做得很差。您的解决方案虽然避免了正则表达式的优雅,但非常笨拙且令人费解。您正在拆分每个字符并进行多次迭代函数调用。没有必要指定一个空字符串作为胶水。我不会在我的一个项目中考虑这个解决方案,因为它没有优雅、可读性低和 n 个不必要的函数调用。
            【解决方案23】:

            这里最差的答案几乎是最好的(使用框架)。不,不要,看看源代码。看看一个完善的框架使用什么将是一种更可靠的方法(经过试验和测试)。 Zend 框架有一些适合您需要的单词过滤器。 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     = ['#(?<=(?:[A-Z]))([A-Z]+)([A-Z][a-z])#', '#(?<=(?:[a-z0-9]))([A-Z])#'];
                    $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");
            

            【讨论】:

              【解决方案24】:

              有一个library 提供此功能:

              SnakeCaseFormatter::run('CamelCase'); // Output: "camel_case"
              

              【讨论】:

              • 我认为您的意思是“我创建了一个提供此功能的库”。自我推销没有错,但不要隐瞒。
              【解决方案25】:

              如果你使用 Laravel 框架,你可以只使用 snake_case() 方法。

              【讨论】:

                【解决方案26】:

                这是一种较短的方法:

                function camel_to_snake($input)
                {
                    return strtolower(ltrim(preg_replace('/([A-Z])/', '_\\1', $input), '_'));
                }
                

                【讨论】:

                • 纯代码答案在 Stackoverflow 上的价值很低,因为它们对教育/授权成千上万的未来研究人员几乎没有作用。
                • @mickmackusa - 未来数以千计的研究人员将对优雅的单行线感兴趣,并进行自我教育。
                • 很抱歉你采取了这种自私的立场。你当然可以在你设计和输入那个尖刻的回复的时候添加一个解释。您的答案进行了三个函数调用,但其他人执行了两个任务。
                【解决方案27】:

                如何在不使用正则表达式的情况下去骆驼化:

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

                编辑:

                2019 年我会怎么做:

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

                以及 PHP 7.4 何时发布:

                function toSnakeCase($str, $glue = '_') {
                    return preg_replace_callback('/[A-Z]/', fn($matches) => $glue . strtolower($matches[0]), $str);
                }
                

                【讨论】:

                • 纯代码答案在 StackOverflow 上的价值很低,因为它们在授权/教育未来研究人员方面做得很差。对字符串中的每个字符进行 1 到 3 次函数调用,然后在循环完成后再进行两次函数调用是非常笨拙的。在经济如此糟糕的情况下,我不会接受解决方案。
                • 这是一个例子,它可以在不使用正则表达式的情况下完成,而不是它应该如何在生产中使用,所以我不明白你的意思,除了你抱怨 5y/o 答案有一个点赞,并且不太可能被任何研究人员看到。
                • 我会关注所有帖子,而不仅仅是高票数或最近的帖子。我不是在抱怨,我是在提出我的批评,以便知识较少的研究人员能够更好地理解这个答案与其他答案之间的区别。你本可以在你的帖子中解释说,避免正则表达式只是一个学术挑战。也就是说,有一些方法可以通过更好的编码实践来提高这个过程的效率。
                【解决方案28】:

                使用 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 >>> 简单测试

                简单>>>简单

                html >>> html

                simple_xml >>> SimpleXml

                pdf_load >>> pdf加载

                start_middle_last >>> StartMiddleLast

                a_string >>> AString

                some4_numbers234 >>> Some4Numbers234

                test123_string >>> Test123String

                -----camelCaseToUnderscore-----

                simpleTest >>> simple_test

                简单>>>简单

                HTML >>> html

                simpleXML >>> simple_xml

                PDFLoad >>> pdf_load

                startMIDDLELast >>> start_middle_last

                字符串 >>> 字符串

                Some4Numbers234 >>> some4_numbers234

                TEST123String >>> test123_string

                【讨论】:

                  【解决方案29】:

                  开源的 TurboCommons 库在 StringUtils 类中包含一个通用的 formatCase() 方法,它允许您将字符串转换为许多常见的大小写格式,例如 CamelCase、UpperCamelCase、LowerCamelCase、snake_case、Title Case 等等。

                  https://github.com/edertone/TurboCommons

                  要使用它,请将 phar 文件导入您的项目,然后:

                  use org\turbocommons\src\main\php\utils\StringUtils;
                  
                  echo StringUtils::formatCase('camelCase', StringUtils::FORMAT_SNAKE_CASE);
                  
                  // will output 'camel_Case'
                  

                  【讨论】:

                    【解决方案30】:
                    $str = 'FooBarBaz';
                    
                    return strtolower(preg_replace('~(?<=\\w)([A-Z])~', '_$1', $str)); // foo_bar_baz
                    

                    【讨论】:

                    • 纯代码答案在 StackOverflow 上的价值很低,因为它们在授权/教育未来研究人员方面做得很差。
                    猜你喜欢
                    • 2015-08-11
                    • 2022-01-19
                    • 2022-07-15
                    • 2023-03-31
                    • 1970-01-01
                    • 2019-07-06
                    • 1970-01-01
                    • 2022-01-25
                    • 2018-06-28
                    相关资源
                    最近更新 更多