만약 내가 가지고 있다면:
$string = "PascalCase";
필요합니다
"pascal_case"
PHP는 이 목적을 위한 기능을 제공합니까?
질문에 대한 답변
보다 짧은 솔루션:정규 표현을 단순화하고 “트레일러링 언더스코어” 문제를 수정한 편집자와 유사합니다.
$output = strtolower(preg_replace('/(?<!^)[A-Z]/', '_$0', $input));
다음과 같은 경우에 따라서는SimpleXML
로 변환됩니다.simple_x_m_l
위의 솔루션을 사용합니다.또한 카멜 대소문자 표기법의 잘못된 사용으로 간주될 수 있습니다(정답은SimpleXml
이러한 경우는 항상 애매하기 때문에 알고리즘의 버그가 아니라1개의 문자열로 대문자를 그룹화해도 됩니다(simple_xml
) 이러한 알고리즘은 다음과 같은 다른 엣지 케이스에서는 항상 실패합니다.XMLHTMLConverter
줄임말 등에 가까운 한 글자 단어(어느 정도 드문) 엣지 케이스에 개의치 않고, 대처하고 싶은 경우SimpleXML
올바르게는, 조금 더 복잡한 솔루션을 사용할 수 있습니다.
$output = ltrim(strtolower(preg_replace('/[A-Z]([A-Z](?![a-z]))*/', '_$0', $input)), '_');
사이즈는 이쪽에서 확인하세요.
$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 => $resultn";
} 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
이것에 의해, 다음의 룰이 실장됩니다.
- 소문자로 시작하는 시퀀스는 소문자와 숫자 뒤에 와야 합니다.
- 대문자로 시작하는 시퀀스 뒤에 다음 중 하나를 사용할 수 있습니다.
- 하나 이상의 대문자 및 숫자(문자열 끝 또는 대문자 뒤에 소문자 또는 숫자(다음 시퀀스의 시작)가 붙습니다) 또는
- 하나 이상의 소문자 또는 숫자.
다음과 같은 까다로운 사용 사례를 처리할 수 있는 간결한 솔루션입니다.
function decamelize($string) {
return strtolower(preg_replace(['/([a-zd])([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 에서 테스트할 수 있습니다.
Symfony Serializer 구성 요소에는 두 가지 방법이 있는 CamelCaseToSnakeCaseNameConverter가 있습니다.normalize()
그리고.denormalize()
이러한 기능은 다음과 같이 사용할 수 있습니다.
$nameConverter = new CamelCaseToSnakeCaseNameConverter();
echo $nameConverter->normalize('camelCase'); // outputs: camel_case
echo $nameConverter->denormalize('snake_case'); // outputs: snakeCase
Ruby’s에서 이식된String#camelize
그리고.String#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 코드로 평가합니다.