Olsaydı:
$string = "PascalCase";
ihtiyacım var
"pascal_case"
PHP bu amaç için bir işlev sunuyor mu?
Olsaydı:
$string = "PascalCase";
ihtiyacım var
"pascal_case"
PHP bu amaç için bir işlev sunuyor mu?
Yanıtlar:
Bunu boyut için 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:
Daha kısa bir çözüm: Düzenleyicinin basitleştirilmiş bir normal ifadeye sahip olana benzer ve "sondaki alt çizgi" sorununu düzeltir:
$output = strtolower(preg_replace('/(?<!^)[A-Z]/', '_$0', $input));
Bu gibi durumların yukarıdaki çözüme SimpleXML
dönüştürüleceğini unutmayın simple_x_m_l
. Bu SimpleXml
, algoritmanın bir hatası yerine deve büyük / küçük harf gösteriminin yanlış kullanımı olarak da düşünülebilir (doğru olacaktır ) çünkü bu tür durumlar her zaman belirsizdir - büyük harfli karakterleri bir dizede gruplandırmakla bile ( simple_xml
) bu tür algoritma diğer uç durumlarda her zaman başarısız olur. XMLHTMLConverter
kısaltmaların yanında benzer veya tek harfli kelimeler, vb. (Oldukça nadir) uç durumları önemsemiyorsanız ve SimpleXML
doğru şekilde ele almak istiyorsanız, biraz daha karmaşık bir çözüm kullanabilirsiniz:
$output = ltrim(strtolower(preg_replace('/[A-Z]([A-Z](?![a-z]))*/', '_$0', $input)), '_');
Kısa bir çözümdür ve bazı zorlu kullanım durumlarının üstesinden gelebilir:
function decamelize($string) {
return strtolower(preg_replace(['/([a-z\d])([A-Z])/', '/([^_])([A-Z][a-z])/'], '$1_$2', $string));
}
Tüm bu durumların üstesinden gelebilir:
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
Bu işlevi burada test edebilirsiniz : http://syframework.alwaysdata.net/decamelize
Ruby'nin String#camelize
ve 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);
}
Yukarıdaki çözümlerin kaçırmış olabileceği bir numara, preg_replace
değiştirme dizesinin PHP kodu olarak değerlendirilmesine neden olan 'e' değiştiricisidir .
e
bayrağı preg_replace
PHP 5.5'te kullanımdan kaldırılıyor.
^|
veya strlen
.
Symfony serileştiricisi Bileşeni bir sahiptir CamelCaseToSnakeCaseNameConverter iki yöntem vardır normalize()
ve denormalize()
. Bunlar şu şekilde kullanılabilir:
$nameConverter = new CamelCaseToSnakeCaseNameConverter();
echo $nameConverter->normalize('camelCase');
// outputs: camel_case
echo $nameConverter->denormalize('snake_case');
// outputs: snakeCase
$nameConverter->normalize('CamelCase')
çıktılar _camel_case
.
Buradaki çoğu çözümün eli ağır geliyor. İşte kullandığım şey:
$underscored = strtolower(
preg_replace(
["/([A-Z]+)/", "/_([A-Z]+)([A-Z][a-z])/"],
["_$1", "_$1_$2"],
lcfirst($camelCase)
)
);
"CamelCASE", "camel_case" biçimine dönüştürülür
lcfirst($camelCase)
ilk karakteri düşürür ('CamelCASE' dönüştürülmüş çıktının alt çizgiyle başlamasını önler)[A-Z]
büyük harfleri bulur+
ardışık her büyük harfe bir kelime olarak davranır ('CamelCASE'in camel_C_A_S_E'ye dönüştürülmesini önler)ThoseSPECCases
-> those_spec_cases
yerinethose_speccases
strtolower([…])
çıkışı küçük harflere çevirirlcfirst
$
ucfirst()
çağrı nedeniyle bu çözüm tarafından beklenmedik bir şekilde bölünecektir . DemoUSADollarSymbol
oluyor Bu çözümü önermiyorum çünkü girdi dizgisinden regex ile iki geçiş yapması gerekiyor - rafine edilmemiş bir modelin işareti. u_sa_dollar_symbol
php bu afaik için yerleşik bir işlev sunmuyor, ama işte kullandığım şey
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 belirtilebilir, böylece onu böyle çağırabilirsiniz
$camelized="thisStringIsCamelized";
echo uncamelize($camelized,"_");
//echoes "this_string_is_camelized"
echo uncamelize($camelized,"-");
//echoes "this-string-is-camelized"
mb_strtolower
ve açık /u
seçeneği ile kolayca yapabilirsiniz preg_replace
.
Başında olması dışında her büyük harfle eşleşen bir normal ifade çalıştırmanız ve onu alt çizgi artı o harfle değiştirmeniz gerekir. Bir utf-8 çözümü şudur:
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_áááá_őőőő
Dizenizin hangi durumda olduğundan emin değilseniz, önce kontrol etmeniz daha iyi olur, çünkü bu kod girdinin veya camelCase
yerine olduğunu varsayar , bu nedenle sonların büyük harfleri varsa bunlara alt çizgi ekleyecektir.underscore_Case
dash-Case
Cletus'tan kabul edilen cevap çok fazla karmaşık bir imho'dur ve sadece latin karakterlerle işe yarar. Bunu gerçekten kötü bir çözüm buluyorum ve neden kabul edildiğini merak ediyorum. TEST123String
İçine dönüştürme test123_string
mutlaka geçerli bir gereklilik değildir. Daha doğrusu basit tutulması ve ayrılmış ABCccc
içine a_b_cccc
yerine ab_cccc
değil kaybetmek Bu şekilde bilgi yapar ve geriye dönüşüm başladığımız aynı dizeyi verir çünkü. Bunu başka bir şekilde yapmak isteseniz bile, (?<!^)\p{Lu}\p{Ll}|(?<=\p{Ll})\p{Lu}
bir normal ifade uzmanı değilseniz, arkasına pozitif bakmadan veya iki normal ifadeyle bir normal ifade yazmak görece kolaydır . Kullanmanın tamamen iyi olacağı arasında strtolower
ve lcfirst
nerede karar vereceğinden bahsetmeye gerek yok, onu alt dizelere ayırmaya gerek yok strtolower
.
Bir PHP 5.4 sürümü ve daha sonraki bir sürümü arıyorsanız, kod şu şekildedir:
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
);
}
Hiç de fantezi değil ama cehennem kadar basit ve hızlı:
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
yerine $i++
biraz daha hızlı hale getirirdi;)
"CamelCase" ile "camel_case":
function camelToSnake($camel)
{
$snake = preg_replace('/[A-Z]/', '_$0', $camel);
$snake = strtolower($snake);
$snake = ltrim($snake, '_');
return $snake;
}
veya:
function camelToSnake($camel)
{
$snake = preg_replace_callback('/[A-Z]/', function ($match){
return '_' . strtolower($match[0]);
}, $camel);
return ltrim($snake, '_');
}
this-kind-of-output
Regex kullanmayan bir sürüm 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);
}
İşte tek satırlık:
strtolower(preg_replace('/(?|([a-z\d])([A-Z])|([^\^])([A-Z][a-z]))/', '$1_$2', $string));
g
bu regex'e bir değiştirici eklemenizi öneririm .
g
ve benim için iyi çalışıyor.
g
. Ama test ettiğim ifadeyi hatırlayamıyorum.
danielstjules / Stringy, dizeyi camelcase'den snakecase'e dönüştürmek için bir yöntem geliştirdi.
s('TestUCase')->underscored(); // 'test_u_case'
Laravel 5.6, bunu yapmanın çok basit bir yolunu sağlar:
/**
* 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;
}
Ne yapar: Verilen dizede en az bir büyük harf olduğunu görürse, herhangi bir karakteri ( ) ve ardından bir büyük harfi ( ) aramak için pozitif bir ilerleme kullanır . Ardından bulunan karakteri değeriyle ve ardından ayırıcıyla değiştirir ..
(?=[A-Z])
_
Raylardan doğrudan bağlantı noktası (:: veya kısaltmalar için özel kullanımları hariç)
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'yi bilmek, burada verilen diğer cevaplarda meydana gelen manuel çözümlemeden daha hızlı olacaktır. Dezavantajı, kelimeler arasında ayırıcı olarak neyi kullanacağınızı seçememenizdir, ancak bu sorunun bir parçası değildi.
Ayrıca ilgili rayların kaynak kodunu kontrol edin
Bunun ASCII tanımlayıcılarla kullanılmak üzere tasarlandığını unutmayın. Bunu ASCII aralığı dışındaki karakterlerle yapmanız gerekiyorsa, '/ u' değiştiricisini preg_match
kullanın ve kullanın mb_strtolower
.
İşte tanrı bilir altı yaşındaki bir soruya katkım kaç cevaptır ...
Sağlanan dizedeki deve harfli tüm kelimeleri yılan kılıfına dönüştürür. Örneğin "SuperSpecialAwesome ve ayrıca FizBuzz καιΚάτιΑκόμα", "super_special_awesome ve ayrıca fizz_buzz και_κάτι_ακόμα" biçimine dönüştürülecektir.
mb_strtolower(
preg_replace_callback(
'/(?<!\b|_)\p{Lu}/u',
function ($a) {
return "_$a[0]";
},
'SuperSpecialAwesome'
)
);
Yii2, snake_case kelimesini CamelCase'den yapmak için farklı bir işleve sahiptir.
/**
* 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));
}
Kısa çözüm:
$subject = "PascalCase";
echo strtolower(preg_replace('/\B([A-Z])/', '_$1', $subject));
Benzer bir sorun yaşadım, ancak alt _
çizgi veya tümü büyük harf kısaltmaları olan adlar için yinelenen veya gereksiz alt çizgilerden kaçınırken, CamelCase'i snake_case'e nasıl dönüştüreceğimi tatmin eden bir yanıt bulamadım .
Sorun şu şekildedir:
CamelCaseClass => camel_case_class
ClassName_WithUnderscores => class_name_with_underscore
FAQ => faq
Yazdığım çözüm basit bir iki işlev çağrısı, küçük harf ve ardışık küçük-büyük harfler için arama ve değiştirme:
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}
(veya $name[$k]
) kullanarak erişebilirsiniz , bu kodunuzu daha uzun hale getirir, ancak bir diziye ve diziden dönüştürmenin büyük ek yükünü önler.
Buradaki en kötü cevap, en iyi olmaya çok yakındı (bir çerçeve kullanın). HAYIR YAPMAYIN, sadece kaynak koduna bir göz atın. İyi kurulmuş bir çerçevenin ne kullandığını görmek çok daha güvenilir bir yaklaşım olacaktır (denenmiş ve test edilmiş). Zend çerçevesi, ihtiyaçlarınıza uyan bazı kelime filtrelerine sahiptir. Kaynak .
İşte kaynaktan uyarladığım birkaç yöntem.
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 framework kullanıyorsanız, sadece snake_case () metodunu kullanabilirsiniz.
Bu, daha kısa yollardan biridir:
function camel_to_snake($input)
{
return strtolower(ltrim(preg_replace('/([A-Z])/', '_\\1', $input), '_'));
}
Normal ifade kullanmadan nasıl deveden arındırılır:
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;
}
Bir düzenleme:
Bunu 2019'da nasıl yaparım:
function toSnakeCase($str, $glue = '_') {
return preg_replace_callback('/[A-Z]/', function ($matches) use ($glue) {
return $glue . strtolower($matches[0]);
}, $str);
}
Ve PHP 7.4 piyasaya çıktığında:
function toSnakeCase($str, $glue = '_') {
return preg_replace_callback('/[A-Z]/', fn($matches) => $glue . strtolower($matches[0]), $str);
}
Zend Kelime Filtrelerinin Filtre sınıflarını kullanmak kolaydır :
<?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 >>> basit_test
kolay >>> kolay
HTML >>> html
simpleXML >>> basit_xml
PDFLoad >>> pdf_load
startMIDDLELast >>> start_middle_last
AString >>> a_string
Some4Numbers234 >>> some4_numbers234
TEST123String >>> test123_string
Açık kaynak TurboCommons kitaplığı, StringUtils sınıfı içinde genel amaçlı bir formatCase () yöntemi içerir; bu, bir dizeyi CamelCase, UpperCamelCase, LowerCamelCase, snake_case, Title Case ve daha pek çok yaygın durum biçimine dönüştürmenize olanak tanır.
https://github.com/edertone/TurboCommons
Kullanmak için, phar dosyasını projenize aktarın ve:
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
Şununla başlayabilirsen:
$string = 'Camel_Case'; // underscore or any other separator...
O zaman sadece şununla her iki duruma da dönüştürebilirsiniz:
$pascal = str_replace("_", "", $string);
$snake = strtolower($string);
Veya diğer durumlar:
$capitalized = str_replace("_", " ", $string); // Camel Case
$constant = strtoupper($string); // CAMEL_CASE
$train = str_replace("_", "-", $snake); // camel-case