내가 만약:
$string = "PascalCase";
나는 필요하다
"pascal_case"
PHP는 이러한 목적을위한 기능을 제공합니까?
내가 만약:
$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
이는 다음 규칙을 구현합니다.
더 짧은 솔루션 : 단순화 된 정규 표현식을 사용하고 "후행 밑줄"문제를 수정하는 편집기의 솔루션과 유사합니다 .
$output = strtolower(preg_replace('/(?<!^)[A-Z]/', '_$0', $input));
이와 같은 경우 는 위의 솔루션 SimpleXML
을 simple_x_m_l
사용하여 변환됩니다 . 또한 SimpleXml
이러한 경우는 항상 모호하기 때문에 알고리즘의 버그 라기보다는 낙타 대소 문자 표기법 (정답은 ) 의 잘못된 사용으로 간주 될 수 있습니다. 대문자를 하나의 문자열 ( simple_xml
) 로 그룹화하더라도 이러한 알고리즘은 항상 다른 경우에 실패합니다. XMLHTMLConverter
약어 근처에있는 like 또는 한 글자 단어 등. (아주 드문 경우) 엣지 케이스에 대해 신경 쓰지 않고 SimpleXML
올바르게 처리 하려면 좀 더 복잡한 솔루션을 사용할 수 있습니다.
$output = ltrim(strtolower(preg_replace('/[A-Z]([A-Z](?![a-z]))*/', '_$0', $input)), '_');
간결한 솔루션이며 까다로운 사용 사례를 처리 할 수 있습니다.
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#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);
}
위의 솔루션이 놓쳤을 수있는 한 가지 트릭은 preg_replace
대체 문자열을 PHP 코드로 평가하는 'e'수정 자입니다 .
e
플래그 preg_replace
는 PHP 5.5에서 더 이상 사용되지 않습니다.
^|
또는 strlen
.
심포니 시리얼 구성 요소 가 CamelCaseToSnakeCaseNameConverter 두 가지 방법이있다 normalize()
및 denormalize()
. 다음과 같이 사용할 수 있습니다.
$nameConverter = new CamelCaseToSnakeCaseNameConverter();
echo $nameConverter->normalize('camelCase');
// outputs: camel_case
echo $nameConverter->denormalize('snake_case');
// outputs: snakeCase
$nameConverter->normalize('CamelCase')
출력 _camel_case
합니다.
여기에있는 대부분의 솔루션은 무겁게 느껴집니다. 내가 사용하는 것은 다음과 같습니다.
$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([…])
출력을 소문자로 바꿉니다.lcfirst
$ camelCase 에 함수 를 추가 하면됩니다
ucfirst()
호출 로 인해이 솔루션에 의해 예기치 않게 분할됩니다 . USADollarSymbol
가된다 u_sa_dollar_symbol
데모 미정 제 패턴의 기호 - 그것은 정규식 입력 문자열을 통해 두 개의 패스를 가지고 있기 때문에이 솔루션을 사용하지 않는 것이 좋습니다.
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"
mb_strtolower
와 /u
에 옵션 preg_replace
.
시작 부분에있는 경우를 제외하고 모든 대문자와 일치하는 정규식을 실행하고 언더 스크 로어와 해당 문자로 대체해야합니다. utf-8 솔루션은 다음과 같습니다.
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_áááá_őőőő
문자열이 어떤 대소 문자인지 확실하지 않은 경우 먼저 확인하는 것이 좋습니다.이 코드는 입력이 또는 camelCase
대신 있다고 가정 하므로 후자에 대문자가 있으면 밑줄이 추가됩니다.underscore_Case
dash-Case
cletus에서 받아 들여지는 대답은 너무 복잡하고 imho이며 라틴 문자에서만 작동합니다. 나는 그것이 정말 나쁜 해결책이라고 생각하고 그것이 왜 받아 들여 졌는지 궁금합니다. 변환 TEST123String
으로하는 것은 test123_string
반드시 유효한 요구하지 않습니다. 차라리 간단하게 유지하고 분리 ABCccc
로 a_b_cccc
대신 ab_cccc
그렇지 잃게 정보이 방법을 수행하고 역방향 변환 우리가 시작 동일한 문자열을 줄 것 때문이. 다른 방식으로하고 싶은 경우에도 (?<!^)\p{Lu}\p{Ll}|(?<=\p{Ll})\p{Lu}
정규식 전문가가 아닌 경우 긍정적 인 lookbehind 또는 두 개의 정규식을 사용하여 정규식을 작성하는 것이 상대적으로 쉽습니다 . 사용하는 것이 완전히 괜찮을 위치 strtolower
와 사이를 결정하는 것은 말할 것도없고 하위 문자열로 분할 할 필요가 없습니다 .lcfirst
strtolower
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
++$i
대신 $i++
뿐만 아니라 그것을 조금 더 빠른을 할 것이다)
"CamelCase"에서 "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, '_');
}
this-kind-of-output
정규식을 사용하지 않는 버전은 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);
}
danielstjules / Stringy 는 문자열을 camelcase에서 snakecase로 변환하는 방법을 제공했습니다.
s('TestUCase')->underscored(); // 'test_u_case'
Laravel 5.6은이를 수행하는 매우 간단한 방법을 제공합니다.
/**
* 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])
. 그런 다음 찾은 문자를 값 뒤에 구분 기호가있는 값으로 바꿉니다 _
.
레일의 직접 포트 (:: 또는 약어에 대한 특수 처리 제외)는 다음과 같습니다.
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_match
사용하고 mb_strtolower
.
여섯 살짜리 질문에 대한 나의 공헌은 하나님이 얼마나 많은 답을 알고 있는지 알고 있습니다 ...
camelcase에있는 제공된 문자열의 모든 단어를 snakecase로 변환합니다. 예를 들어 "SuperSpecialAwesome 및 FizBuzz καιΚάτιΑκόμα"는 "super_special_awesome 및 fizz_buzz και_κάτι_ακόμα"로 변환됩니다.
mb_strtolower(
preg_replace_callback(
'/(?<!\b|_)\p{Lu}/u',
function ($a) {
return "_$a[0]";
},
'SuperSpecialAwesome'
)
);
Yii2는 CamelCase에서 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));
}
짧은 솔루션 :
$subject = "PascalCase";
echo strtolower(preg_replace('/\B([A-Z])/', '_$1', $subject));
비슷한 문제가 있었지만 중복 또는 중복 밑줄을 피하면서 CamelCase를 snake_case로 변환하는 방법을 만족시키는 답을 찾을 수 없었습니다. _
이있는 이름이나 모두 대문자 약어에 대해 을 .
문제는 다음과 같습니다.
CamelCaseClass => camel_case_class
ClassName_WithUnderscores => class_name_with_underscore
FAQ => faq
내가 작성한 솔루션은 소문자와 연속 소문자 대문자 검색 및 바꾸기라는 간단한 두 가지 함수를 호출하는 것입니다.
strtolower(preg_replace("/([a-z])([A-Z])/", "$1_$2", $name));
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);
}
$name{$k}
(또는 $name[$k]
)을 사용하여 문자에 직접 액세스 할 수 있습니다. 이렇게하면 코드가 더 길어 지지만 배열과 배열간에 변환하는 큰 오버 헤드를 피할 수 있습니다.
여기에 대한 최악의 대답은 최고 (프레임 워크 사용)에 너무 가깝습니다. 아니요, 소스 코드를 살펴보십시오. 잘 확립 된 프레임 워크가 사용하는 것을 보는 것이 훨씬 더 신뢰할 수있는 접근 방식 (시도 및 테스트)이 될 것입니다. 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");
Laravel 프레임 워크를 사용하는 경우 snake_case () 메소드 만 사용할 수 있습니다 .
이것은 더 짧은 방법 중 하나입니다.
function camel_to_snake($input)
{
return strtolower(ltrim(preg_replace('/([A-Z])/', '_\\1', $input), '_'));
}
정규식을 사용하지 않고 낙타를 제거하는 방법 :
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);
}
Zend Word Filters 의 Filter 클래스를 사용하는 것은 쉽습니다 .
<?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
오픈 소스 TurboCommons 라이브러리에는 StringUtils 클래스 내에 범용 formatCase () 메서드가 포함되어있어 문자열을 CamelCase, UpperCamelCase, LowerCamelCase, snake_case, Title Case 등과 같은 많은 일반적인 케이스 형식으로 변환 할 수 있습니다.
https://github.com/edertone/TurboCommons
이를 사용하려면 phar 파일을 프로젝트로 가져오고 다음을 수행하십시오.
use org\turbocommons\src\main\php\utils\StringUtils;
echo StringUtils::formatCase('camelCase', StringUtils::FORMAT_SNAKE_CASE);
// will output 'camel_Case'
$str = 'FooBarBaz';
return strtolower(preg_replace('~(?<=\\w)([A-Z])~', '_$1', $str)); // foo_bar_baz
다음으로 시작할 수 있다면 :
$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