Как преобразовать PascalCase в pascal_case?

Если я имел:

$string = "PascalCase";

Мне нужно

"pascal_case"

PHP предлагает функцию с этой целью?

106
задан mickmackusa 8 May 2019 в 12:05
поделиться

3 ответа

Примерьте это для размера:

$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. За последовательностью, начинающейся с прописной буквы, может последовать любая из них:
    • одна или несколько заглавных букв и цифр (за которыми следует либо конец строки, либо заглавная буква, а затем строчная буква или цифра, т.е. начало следующей последовательности); или
    • одна или несколько строчных букв или цифр.
151
ответ дан 24 November 2019 в 03:44
поделиться

Версию, которая не использует регекс, можно найти в Alchitect source:

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
ответ дан 24 November 2019 в 03:44
поделиться

PHP не предлагает встроенную функцию для этого afaik, но вот что я использую

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

}

Splitter можно указать в вызове функций, чтобы вы могли назвать это так

$camelized="thisStringIsCamelized";
echo uncamelize($camelized,"_");
//echoes "this_string_is_camelized"
echo uncamelize($camelized,"-");
//echoes "this-string-is-camelized"
18
ответ дан 24 November 2019 в 03:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: