如果我有:

$string = "PascalCase";

我需要的

"pascal_case"

不PHP提供了一个功能,用于这一目的?

有帮助吗?

解决方案

试试这个尺寸:

$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. 序列初用大写字母可随后通过:
    • 一个或多个大写字母和数字(随后通过的结束串或一个大写字母然后一个小写信或数字即将开始的下一个顺序);或
    • 一个或一个小写字母或数字。

其他提示

一个更短的溶液:以类似的编辑的的一个具有简化的正则表达式和固定“后下划线”的问题:

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

PHP演示 | 正则表达式演示


注意,像SimpleXML例将使用上述溶液被转化为simple_x_m_l。这也可以被认为是骆驼符号的错误使用(正确的是SimpleXml),而不是因为这种情况下,算法的错误总是模棱两可 - 甚至大写字符分组到一个字符串(simple_xml)这样的算法总是在其他失败边缘情况下,像附近的缩写,等等XMLHTMLConverter或一个字母的单词。如果你不介意有关(相当罕见的)边缘的情况下,想把手SimpleXML正确,你可以用一个稍微复杂的解决方案:

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

PHP演示 | 正则表达式演示

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

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

阀块从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代码。

解器的成分 有一个 CamelCaseToSnakeCaseNameConverter 有两种方法 normalize()denormalize().这些可以用如下:

$nameConverter = new CamelCaseToSnakeCaseNameConverter();

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

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

大多数方案在这里感觉沉重的移交。这里就是我的使用:

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

"驼峰式"转换为"camel_case"

  • lcfirst($camelCase) 将下第一个字符的(可以避免'驼峰式'转换输出到开始带有下划线)
  • [A-Z] 发现大写字母
  • + 将把每连续写作为一个词语(可以避免'驼峰式'可转换为camel_C_A_S_E)
  • 第二个模式和替换为 ThoseSPECCases -> those_spec_cases 而不是的 those_speccases
  • strtolower([…]) 轮流输出为小写

PHP不提供在功能上内置了这个据我所知,但这里是我使用

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

如果你正在寻找一个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
    );

} 

在所有但简单和迅速的地狱不花哨:

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

“驼峰” 到 “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, '_');
}

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

因此,这里是一个班轮:

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

danielstjules /包含字符串的防阻从驼峰到snakecase转换字符串的方法。

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

5.6 Laravel提供这样做的非常简单的方法:

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

做些什么:如果看到有给定字符串中至少一个大写字母,它采用的正向前查找搜索任何字符(.)后跟一个大写字母((?=[A-Z]))。然后,它替换它的值所找到的字符随后separactor _

从轨道的直接端口(减去它们对特殊处理::或首字母缩写)。将

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,这将是比这是发生在这里给出其他答案手动解析速度更快。缺点是,你不要去选择什么作为单词之间的分隔符,但是这不是问题的一部分。

同时检查相关轨道源代码

注意,这是用于与ASCII标识符的使用。如果您需要的字符之外做ASCII范围这一点,使用“/ U”修饰符preg_matchand使用mb_strtolower

下面是我与神六十岁的问题贡献知道有多少的答案......

将转换所提供的串中是首字母大写的snakecase所有单词。例如, “SuperSpecialAwesome并且还FizBuzzκαιΚάτιΑκόμα” 将被转换为 “super_special_awesome并且还fizz_buzzκαι_κάτι_ακόμα”。

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

Yii2具有不同的功能,以使从驼峰字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));
    }
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);
}

有一个提供此功能:

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

如果您使用Laravel框架,可以使用刚刚 snake_case()方法

$str = 'FooBarBaz';

return strtolower(preg_replace('~(?<=\\w)([A-Z])~', '_$1', $str)); // foo_bar_baz

这是短的方式之一:

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

如何去camelize不使用正则表达式:

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

短溶液:

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

有使用Zend 字的过滤器类很容易过滤器

<?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的

     

容易>>>易

     

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

     

容易>>>容易

     

HTML HTML >>>

     

的SimpleXML >>> simple_xml

     

PDFLoad >>> pdf_load

     

startMIDDLELast >>> start_middle_last

     

ASTRING >>>此处a_string

     

Some4Numbers234 >>> some4_numbers234

     

TEST123String >>> test123_string

在这里最糟糕的答案是如此接近是最好的(使用的框架)。 NO不这样做,只是看看源代码。看到的一个完善的框架使用将是一个更为可靠的办法(试用和测试)。 Zend框架有哪些适合您的需求的一些词的过滤器。

这里是一对夫妇的我适于从所述源的方法。

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

在开源TurboCommons库包含StringUtils类,它可以让你将字符串转换为很多常见的情况格式,如驼峰,UpperCamelCase,LowerCamelCase,snake_case,标题案例,和许多内部通用formatCase()方法。

https://github.com/edertone/TurboCommons

要使用它,导入药业文件到您的项目和:

use org\turbocommons\src\main\php\utils\StringUtils;

echo StringUtils::formatCase('camelCase', StringUtils::FORMAT_SNAKE_CASE);

// will output 'camel_Case'

我也有类似的问题,但找不到任何答案是满足如何驼峰转换为snake_case,同时避免重复或冗余下划线_用下划线或全部大写缩写名称。

钍的问题是像如下:

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

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

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

如果你可以用启动:

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

然后,你可以转换成任何一种情况下只是:

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

或者任何其他情况下:

$capitalized = str_replace("_", " ", $string); // Camel Case
$constant = strtoupper($string);               // CAMEL_CASE
$train = str_replace("_", "-", $snake);        // camel-case
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top