CamelCase camel_case dönüştürmek nasıl?

11 Cevap php

Ben olsaydı:

$string = "CamelCase";

İhtiyacım

"camel_case"

PHP bu amaçla bir işlev sunuyor mu?

11 Cevap

Boyutu için bu deneyin:

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

Çıktı:

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

Bu aşağıdaki kuralları uygular:

  1. Küçük harfle başlayan bir dizi küçük harf ve rakamlardan tarafından takip edilmelidir;
  2. A sequence beginning with an uppercase letter can be followed by either:
    • (dizenin sonunda veya bir sonraki dizinin başlangıcından yani küçük harf veya rakam izlediği bir büyük harfle ardından ya) bir veya birden fazla büyük harf ve rakam; veya
    • Bir veya küçük harf veya rakam daha fazla.

Ruby'nin String#camelize ve String#decamelize taşıdık.

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

Yukarıdaki çözümler kaçırmış olabilir biri hile preg_replace PHP kodu olarak değiştirme dizesini değerlendirmek için neden 'e' değiştirici olduğunu.

php bir bu afaik için fonksiyon inşa sunuyoruz, ama burada ne kullanın değil

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

}

ayırıcı işlev çağrısında belirtilen olabilir, bu yüzden bunu böyle arayabilirsiniz

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

Burada çoğu çözümler eli ağır hissediyorum. İşte ne kullanın:

$underscored = strtolower( preg_replace( '/([A-Z])/', '_$1', $camelCase ) );

Bu "a_String" içine "aString" döner ve daha sonra küçük harflerle.

editor's birine benzer çok basit bir çözüm, ama biraz basitleştirilmiş regex ve "firar-undersocre" sorunu gidermekle ile:

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

(Ve evet, kabul cevabı bir FAIL.)

Regex kullanmayan bir versiyonu Alchitect kaynağında bulunabilir:

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);
}
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_áááá_őőőő

(Kabul edilen "çözüm" ... epik bir fail)

Bu Zend Word Filters in Filtre sınıfları kullanarak kolay:

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

Kolay Kolay >>>

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

kolay kolay >>>

HTML >>> html

SimpleXML >>> simple_xml

PDFLoad >>> pdf_load

startMIDDLELast >>> start_middle_last

AString >>> a_string

Some4Numbers234 >>> some4_numbers234

TEST123String >>> test123_string

Ben yöntem decamelization için kullanmak ne:

function decamelize($str, $glue='_') {
  $capitals = array();
  $replace  = array();

  foreach(str_split($str) as $index => $char) {
     if(ord($char) >= 65 && ord($char) <= 90) {
        $capitals[] = $char;
        $replace[] = ($index > 0 ? $glue : '').strtolower($char);
     }
  }

  if(sizeof($capitals)) return str_replace($capitals, $replace, $str);

  return $str;
}

Raylar doğrudan port (eksi :: ya da kısaltmalar için kendi özel taşıma) olacaktır

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 bilerek, bu burada verilen diğer yanıtlar oluyor manuel ayrıştırma daha hızlı olacaktır. Dezavantajı kelimeler arasında ayırıcı olarak kullanmak için ne seçilmek için alamadım, ama bu sorunun bir parçası değildi.

Ayrıca relevant rails source code kontrol

Bu ASCII tanımlayıcıları ile kullanım için tasarlanmıştır unutmayın. Eğer, ASCII aralığının dışında karakterleri ile bunu preg_match için '/ u' değiştirici kullanmak ve kullanmak gerekiyorsa mb_strtolower.

Fantezi değil ama basit ve hızlı cehennem gibi:

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