[php] PascalCase를 pascal_case로 변환하는 방법?

내가 만약:

$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 데모 |
Regex 데모


이와 같은 경우 는 위의 솔루션 SimpleXMLsimple_x_m_l사용하여 변환됩니다 . 또한 SimpleXml이러한 경우는 항상 모호하기 때문에 알고리즘의 버그 라기보다는 낙타 대소 문자 표기법 (정답은 ) 의 잘못된 사용으로 간주 될 수 있습니다. 대문자를 하나의 문자열 ( simple_xml) 로 그룹화하더라도 이러한 알고리즘은 항상 다른 경우에 실패합니다. XMLHTMLConverter약어 근처에있는 like 또는 한 글자 단어 등. (아주 드문 경우) 엣지 케이스에 대해 신경 쓰지 않고 SimpleXML올바르게 처리 하려면 좀 더 복잡한 솔루션을 사용할 수 있습니다.

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

PHP 데모 |
Regex 데모


답변

간결한 솔루션이며 까다로운 사용 사례를 처리 할 수 ​​있습니다.

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

위의 솔루션이 놓쳤을 수있는 한 가지 트릭은 preg_replace대체 문자열을 PHP 코드로 평가하는 ‘e’수정 자입니다 .


답변

심포니 시리얼 구성 요소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)
    )
);

“CamelCASE”는 “camel_case”로 변환됩니다.

  • lcfirst($camelCase) 첫 번째 문자를 낮 춥니 다 ( ‘CamelCASE’로 변환 된 출력이 밑줄로 시작하지 않도록합니다)
  • [A-Z] 대문자를 찾습니다
  • + 연속 된 모든 대문자를 단어로 처리합니다 ( ‘CamelCASE’가 camel_C_A_S_E로 변환되는 것을 방지 함).
  • 두 번째 패턴 및 대체는 ThoseSPECCases-> those_spec_cases대신those_speccases
  • strtolower([…]) 출력을 소문자로 바꿉니다.

답변

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"