PascalCase को pascal_case में कैसे बदलें?


115

अगर मैं होता:

$string = "PascalCase";

मुझे जरूरत है

"pascal_case"

क्या PHP इस उद्देश्य के लिए एक फ़ंक्शन प्रदान करता है?


31
तकनीकी रूप से, पहला उदाहरण स्ट्रिंग PascalCase है।
रॉबिन वैन बालन

33
और दूसरा उदाहरण स्ट्रिंग snake_case के रूप में जाना जाता है ।
पैंग

जवाबों:


163

आकार के लिए इसे पहनकर देखें:

$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. एक अपरकेस अक्षर से शुरू होने वाले अनुक्रम का अनुसरण या तो किया जा सकता है:
    • एक या अधिक अपरकेस अक्षर और अंक (इसके बाद या तो स्ट्रिंग के अंत में या एक अपरकेस अक्षर के बाद एक लोअरकेस अक्षर या अंक अर्थात अगले अनुक्रम की शुरुआत); या
    • एक या अधिक लोअरकेस अक्षर या अंक।

9
यह कैमेलकेड स्ट्रिंग्स (जैसा कि ओपनफ्रॉग ने पूछा गया) के लिए काम करता है, लेकिन अगर आप इसे "r_id" (पहले से "अंडरस्कोर") उदाहरण के लिए इनपुट स्ट्रिंग के साथ उपयोग करते हैं, तो यह उपसर्ग ("r_") को ट्रिम कर देता है। अच्छा समाधान, लेकिन निश्चित रूप से सार्वभौमिक नहीं है।
मार्टिन

1
उत्सुक क्यों आप जाँच कर रहे हैं कि स्ट्रिंग ऑल-कैप स्ट्रिंग से मेल खाती है? केवल प्रथम चरित्र को लोअरकेस में परिवर्तित करने का क्या लाभ है (सभी वर्णों के विपरीत)?
जोश

1
एक अधिक संक्षिप्त समाधान जो इन सभी उपयोग मामलों को भी संभाल सकता है: stackoverflow.com/a/35719689/4328383
10

156

एक छोटा समाधान: सरल नियमित अभिव्यक्ति के साथ संपादक के समान और "ट्रेलिंग-अंडरस्कोर" समस्या को ठीक करना:

$output = strtolower(preg_replace('/(?<!^)[A-Z]/', '_$0', $input));

PHP डेमो | रेगेक्स डेमो


ध्यान दें कि उपरोक्त समाधानों का उपयोग SimpleXMLकरने के लिए simple_x_m_lइस तरह के मामलों को परिवर्तित किया जाएगा । यह भी ऊंट मामले संकेतन का एक गलत उपयोग माना जा सकता है (सही होगा SimpleXml) एल्गोरिथ्म की एक बग के बजाय क्योंकि ऐसे मामले हमेशा अस्पष्ट होते हैं - यहां तक ​​कि अपरकेस वर्णों को एक स्ट्रिंग में शामिल करके ( simple_xml) ऐसा एल्गोरिथ्म हमेशा अन्य मामलों में विफल होगा XMLHTMLConverterसंक्षिप्तीकरण आदि के पास एक या एक अक्षर के शब्द जैसे , यदि आप (बल्कि दुर्लभ) किनारे के मामलों के बारे में बुरा नहीं मानते हैं और SimpleXMLसही तरीके से संभालना चाहते हैं , तो आप थोड़ा और जटिल समाधान का उपयोग कर सकते हैं:

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

PHP डेमो | रेगेक्स डेमो


बेझिझक टिप्पणी करने के लिए 'cletus' का उत्तर दें जो आपके द्वारा तय किए गए मामलों का परीक्षण करता है।
माइक बी

3
मैं यह नहीं कह रहा कि उसका समाधान गलत परिणाम देता है। उसका समाधान सिर्फ बेहद जटिल और अप्रभावी है।
Jan Jakeš

1
हां, स्वीकार जवाब निश्चित रूप से विफल है। जान का हल कमाल! एक साइड नोट के रूप में, मुझे लगता है कि यह (या थोड़ी भिन्नता) PHP डेवलपर्स के लिए मेरा नया, पसंदीदा कोडिंग टेस्ट है, क्योंकि इस सवाल के लिए दिए गए उत्तरों की संख्या है कि वास्तव में काम नहीं करना अविश्वसनीय है। यह प्रारंभिक फ़िल्टरिंग करने का एक शानदार तरीका होगा। :-)
जेम्सगैस

इस समाधान में प्रयुक्त रेगेक्स बहुत अधिक पूर्ण पाया गया: stackoverflow.com/questions/2559759/…
वक्ष

2
साधारण उपयोग के मामलों के लिए अच्छा समाधान और ज्यादातर सामान्य मामलों में यह पर्याप्त है लेकिन स्वीकृत समाधान अधिक उपयोग के मामलों को संभाल सकता है, उदाहरण के लिए "simpleXML" को "simple_xml" में परिवर्तित किया जा सकता है और "simple_x_m_l" नहीं
Syone

35

एक संक्षिप्त समाधान और कुछ मुश्किल मामलों का उपयोग कर सकते हैं:

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


@VivekVardhan इस रेगेक्स के किस हिस्से को आप नहीं समझते हैं?
सायोन

उह, मुझे लगता है कि नॉन कैमलकेस स्ट्रिंग्स को कम करना एक साइड इफेक्ट है, अगर स्ट्रिंग ऊंट के मामले में नहीं है, तो मूल को वापस कर देना चाहिए। यदि आप 'simple_Text' भेजते हैं, तो आप प्रभावित हो जाते हैं: सरल_Test => simple_Test [simple_test]। लोअरस्किंग स्ट्रिंग केवल बनाया जाना चाहिए और यदि केवल मूल स्ट्रिंग एक वास्तविक ऊंट केस स्ट्रिंग है। तुम क्या सोचते हो?
गुइडो

24

रूबी 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प्रतिस्थापन कोड का मूल्यांकन पीएचपी कोड के रूप में करता है।


10
के लिए eध्वज preg_replacePHP 5.5 में चित्रित किया जा रहा है।
cdmckay

BTW ये रूबी में या तो नहीं हैं, लेकिन रेल के इनफ्लेक्टर लाइब्रेरी में - कैमलाइज़ और अंडरस्कोर। api.rubyonrails.org/classes/ActiveSupport/Inflector.html
mahemoff

2
यह "ThisIsATest" के लिए विफल रहता है। ऐसा लगता है जो लगातार दो अपरकेस का समर्थन नहीं करता है।
ओनाबाई

बस एक ध्यान दें: आप पहले अक्षर को नीचे लाने के लिए lcfirst का उपयोग कर सकते हैं, फिर आपको इसकी आवश्यकता नहीं है ^|या strlen
बेनुबर्ड

डीरेकाज को बिना अपचयन के: gist.github.com/scones/e09c30e696246fda14578bcf8ab4910a
scones

23

Symfony Serializer घटक एक है CamelCaseToSnakeCaseNameConverter दो विधियों है कि normalize()और denormalize()। इन्हें निम्नानुसार इस्तेमाल किया जा सकता है:

$nameConverter = new CamelCaseToSnakeCaseNameConverter();

echo $nameConverter->normalize('camelCase');
// outputs: camel_case

echo $nameConverter->denormalize('snake_case');
// outputs: snakeCase

1
सावधान रहें! Symfony Serializer घटक के वर्तमान संस्करण 3.2 में $nameConverter->normalize('CamelCase')आउटपुट _camel_case
१३'१ '

21

यहां ज्यादातर समाधान भारी हाथ लगता है। यहाँ मेरा उपयोग है:

$underscored = strtolower(
    preg_replace(
        ["/([A-Z]+)/", "/_([A-Z]+)([A-Z][a-z])/"], 
        ["_$1", "_$1_$2"], 
        lcfirst($camelCase)
    )
);

"CamelCASE" को "camel_case" में बदल दिया गया है

  • lcfirst($camelCase) पहले वर्ण को कम कर देगा (अंडरसेलकोर के साथ शुरू करने के लिए 'कैमलकेयर' परिवर्तित आउटपुट से बचा जाता है)
  • [A-Z] बड़े अक्षरों का पता लगाता है
  • + हर लगातार अपरकेस को एक शब्द के रूप में मानेंगे ('CamelCASE' से बचता है जिसे camel_C_A_S_E में परिवर्तित किया जाता है)
  • दूसरा पैटर्न और प्रतिस्थापन इसके बजाय ThoseSPECCases-> those_spec_casesके लिए हैthose_speccases
  • strtolower([…]) आउटपुट को लोअरकेस में बदल देता है

3
लेकिन यह कैमकल्ड को _camel_cased भी कर देता है।
acme

1
यह बहुत अच्छा है - बस उस मुद्दे को हल करने के लिए char 1 पर शुरू होने वाले एक पदार्थ को जोड़ें।
Oddman

4
उत्कृष्ट! बस lcfirst$ camelCase में फ़ंक्शन जोड़ने की आवश्यकता है
एडाकोस

स्वीकृत उत्तर संभाल लेंगे: TestUPSClass test_ups_class में जबकि यह test_u_p_s_class में बदल जाएगा, कुछ ध्यान में रखना होगा।
मजाज़

एक इनपुट स्ट्रिंग जो पहले "शब्द" से शुरू होती है, ucfirst()कॉल के कारण इस समाधान से अप्रत्याशित रूप से विभाजित हो जाएगी । डेमोUSADollarSymbol हो जाता है मैं इस समाधान की सिफारिश नहीं करता हूं, क्योंकि इसे regex के साथ इनपुट स्ट्रिंग के माध्यम से दो पास करना पड़ता है - एक अपरिष्कृत पैटर्न का संकेत। u_sa_dollar_symbol
मिकमैकुसा

19

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"

2
यह "ThisIsATest" के लिए विफल रहता है। ऐसा लगता है जो लगातार दो अपरकेस का समर्थन नहीं करता है।
ओनाबाई

निश्चित रूप से आप कुछ भूल गए क्योंकि दूसरा प्रतिस्थापन कुछ नहीं करता है। इसके अलावा, आप इसे आसानी से यूनिकोड के साथ mb_strtolowerऔर /uविकल्प पर संगत बना सकते हैं preg_replace
बोडो

8

आपको इसके माध्यम से एक रेगेक्स चलाने की आवश्यकता है जो कि प्रत्येक अपरकेस पत्र से मेल खाता है, भले ही यह शुरुआत में हो और इसे अंडरस्कोर प्लस के साथ बदलें। एक 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, इसलिए यदि लैटर्स में अपरकेस अक्षर हैं, तो यह उनके लिए अंडरस्कोर जोड़ देगा।

क्लेटस से स्वीकृत उत्तर वैसे भी बहुत अधिक नकल है और यह केवल लैटिन वर्णों के साथ काम करता है। मुझे लगता है कि यह वास्तव में बुरा समाधान है और मुझे आश्चर्य है कि इसे बिल्कुल स्वीकार क्यों किया गया। परिवर्तित TEST123Stringमें test123_stringजरूरी एक वैध आवश्यकता नहीं है। मैंने बल्कि इसे सरल रखा और इसके बजाय इसे अलग ABCcccकर a_b_ccccदिया ab_ccccक्योंकि यह इस तरह से जानकारी नहीं खोता है और पीछे का रूपांतरण उसी स्ट्रिंग को देगा जो हमने शुरू किया था। यहां तक ​​कि अगर आप इसे दूसरे तरीके से करना चाहते हैं, भले ही आप (?<!^)\p{Lu}\p{Ll}|(?<=\p{Ll})\p{Lu}रिजेक्स विशेषज्ञ नहीं हैं, तो पॉज़िटिव लुकबाइंड या दो रेगेक्स के साथ रेगेक्स लिखना आसान नहीं है। वहाँ नहीं करने के लिए बीच में निर्णय लेने का उल्लेख नहीं है strtolowerऔर lcfirstजहां का उपयोग कर strtolowerपूरी तरह से ठीक हो जाएगा को विभाजित करने की आवश्यकता नहीं है।


कोड-ओनली उत्तर स्टैकओवरफ़्लो पर कम मूल्य हैं क्योंकि वे हजारों भविष्य के शोधकर्ताओं को शिक्षित / सशक्त बनाने के लिए बहुत कम करते हैं।
मिकमैकुसा

@mickmackusa यदि शोधकर्ता सीखते हैं कि एसओ से कोड कैसे लिया जाता है, तो हमें एक गंभीर समस्या है ...
inf3rno

अब जब आपको अपने सिस्टम से वह निजी हमला मिल गया है, तो कृपया अपने उत्तर में सुधार करें। यह मानते हुए कि आप जानते हैं कि आपका समाधान कैसे काम करता है और आप उन पैटर्न संशोधक का उपयोग क्यों कर रहे हैं, मुझे इस समुदाय से ज्ञान वापस लेने का कोई अच्छा कारण नहीं दिखता है। यदि आप अधिक कर्कश प्रतिक्रियाओं को छोड़ने पर विचार कर रहे हैं, तो मैं आपको विश्वास दिलाता हूं कि वे मुझे परेशान नहीं करते। जिस समय आपने टिप्पणी की है, आप अपना उत्तर पूरा कर सकते थे, हम अपनी टिप्पणियों को हटा सकते थे, और मैं इस साइट की मदद करने के लिए कहीं और जा सकता था।
मिकमैकुसा

बेशक, मेरे पास 8 upvotes वाली पोस्ट हटाने का कोई अधिकार नहीं है। यदि आप चाहें, तो आप अपना उत्तर हटा सकते हैं, लेकिन अनावश्यक पैटर्न संशोधक को हटाकर और स्पष्टीकरण जोड़कर इसे सुधारना बहुत कठिन नहीं होगा। व्यक्तिगत हमलों का मुझ पर कोई प्रभाव नहीं है।
मिकमैकुसा

@mickmackusa मुझे नहीं लगता कि मैं इसे हटा भी सकता हूं। यदि आप चाहते हैं तो इसे संपादित करने के लिए स्वतंत्र महसूस करें।
inf3rno

6

यदि आप एक 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
    );

} 

camelize उपज "SmsSent" sms_sent के लिए, आप एक lcfirst जरूरत है
mik3fly-4steri5k

4

सभी के लिए फैंसी नहीं बल्कि साधारण और तेज नरक के रूप में:

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++यह थोड़ा तेज होगा;)
मैथ्यू एमियोट

कोड-ओनली उत्तर स्टैकओवरफ़्लो पर कम मूल्य हैं क्योंकि वे हजारों भविष्य के शोधकर्ताओं को शिक्षित / सशक्त बनाने के लिए बहुत कम करते हैं।
मिकमैकुसा 22

4

"कैमलकेस" से "कैमलकेस":

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
thexpand

3

एक संस्करण जो रेगेक्स का उपयोग नहीं करता है वह अल्कक्टेक्ट स्रोत में पाया जा सकता है :

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

1
यह वही है जो जीवन रेगेक्स के बिना होगा :-)
ekhaled

4
हे, हाँ। RegEx निश्चित रूप से इसके फायदे हैं। :) कच्ची गति उनमें से एक नहीं है।
डेरेल ब्रोगडन

कुछ कारणों से इस एक के साथ कुछ अजीब परिणाम मिले
mr1031011

इस स्ट्रिंग के आधार पर मेरे लिए काम नहीं करता: "CamelCaseTestAAATestAA", के पास होना चाहिए: "camel_case_test_a_a_a_test_a_a", है: "" camel_test_aest_aest "...
Sybio

3

तो यहाँ एक लाइनर है:

strtolower(preg_replace('/(?|([a-z\d])([A-Z])|([^\^])([A-Z][a-z]))/', '$1_$2', $string));

अच्छा लगा, लेकिन यह केवल पहली उपस्थिति को परिवर्तित करता है, इसलिए मैं gइस रेगेक्स में एक संशोधक जोड़ने की सलाह दूंगा।
acme

@acme, मैं इसके बिना उपयोग करता हूं gऔर यह मेरे लिए ठीक काम करता है।
seelts

मेरे मामले में किसी कारण के लिए मुझे जोड़ना पड़ा g। लेकिन मैं उस वाक्यांश को याद नहीं रख सकता, जिसका मैंने परीक्षण किया था।
acme

3

danielstjules / Stringy ने कैमलकेस से स्ट्रिंग को सॉनेसेज़ में बदलने की एक विधि साबित की।

s('TestUCase')->underscored(); // 'test_u_case'

3

लारवेल 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]))। इसके बाद पाया गया अक्षर बदल देता है और इसके बाद विभाजक का मान होता है _


इस फ़ंक्शन को अब snake_case () कहा जाता है और वैश्विक नाम स्थान में रहता है।
वॉटु

2

रेल से सीधा बंदरगाह (& #: या परिवर्णी के लिए उनकी विशेष हैंडलिंग माइनस) होगा

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


यदि आप बस एक पैरामीटर जोड़ सकते हैं जिसमें वांछित चरित्र है।
फ्लेशग्रिंडर

2

यहाँ भगवान के साथ एक छह साल पुराने सवाल पर मेरा योगदान है कि कितने जवाब हैं ...

यह प्रदान किए गए स्ट्रिंग में सभी शब्दों को रूपांतरित कर देगा जो ऊंट में snakecase में हैं। उदाहरण के लिए "SuperSpecialAwesome और भी FizBuzz ΚάταιΑκόιαμα" को "super_special_awesome और भी fizz_buzz και_κάτι_ακόμα" में परिवर्तित किया जाएगा।

mb_strtolower(
    preg_replace_callback(
        '/(?<!\b|_)\p{Lu}/u',
        function ($a) {
            return "_$a[0]";
        },
        'SuperSpecialAwesome'
    )
);

2

Yii2 शब्द को CamelCase से स्नेक_केस बनाने के लिए अलग-अलग फ़ंक्शन है।

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


2

मेरे पास भी ऐसी ही समस्या थी, लेकिन ऐसा कोई जवाब नहीं मिला जो संतुष्ट करता हो कि कैमलकेस को स्नेक_केस में कैसे बदला जाए, जबकि _अंडरस्कोर, या सभी कैप्स के संक्षिप्त नाम के साथ डुप्लिकेट या निरर्थक अंडरस्कोर को टालना ।

गु समस्या इस प्रकार है:

CamelCaseClass            => camel_case_class
ClassName_WithUnderscores => class_name_with_underscore
FAQ                       => faq

मैंने जो हल लिखा है वह एक सरल दो फ़ंक्शन कॉल, लोअरकेस और खोज है और लगातार लोअरकेस-अपरकेस अक्षरों के लिए प्रतिस्थापित करता है:

strtolower(preg_replace("/([a-z])([A-Z])/", "$1_$2", $name));

अब तक यह सबसे संक्षिप्त और उपयोगी समाधान IMO है।
श्री।

1
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]) का उपयोग करके वर्णों तक पहुंच सकते हैं , जो आपके कोड को लंबा कर देगा, लेकिन इसे एक सरणी से और इसके लिए परिवर्तित करने के बड़े ओवरहेड से बचा जाता है।
बोडो

कोड-ओनली उत्तर स्टैकओवरफ़्लो पर कम मूल्य हैं क्योंकि वे भविष्य के शोधकर्ताओं को सशक्त / शिक्षित करने का एक खराब काम करते हैं। रेगेक्स की कृपा से परहेज करते हुए आपका समाधान बहुत भारी-भरकम और जटिल है। आप प्रत्येक वर्ण पर विभाजन कर रहे हैं और कई पुनरावृत्त फ़ंक्शन कॉल कर रहे हैं। खाली स्ट्रिंग को नामांकित करना गोंद के रूप में अनावश्यक है। मैं अपनी परियोजनाओं में से एक में इस समाधान का मनोरंजन नहीं होगा कोई लालित्य, कम पठनीयता है वहाँ है, और क्योंकि n अनावश्यक समारोह कॉल की संख्या।
मिकमैकुसा

1

यहाँ पर सबसे खराब उत्तर सबसे अच्छा होने के करीब था (एक रूपरेखा का उपयोग करें)। नहीं, बस स्रोत कोड पर एक नज़र रखना। यह देखते हुए कि एक अच्छी तरह से स्थापित रूपरेखा का उपयोग क्या अधिक विश्वसनीय दृष्टिकोण (कोशिश और परीक्षण) होगा। ज़ेंड फ्रेमवर्क में कुछ शब्द फिल्टर हैं जो आपकी आवश्यकताओं के अनुरूप हैं। स्रोत

यहाँ कुछ तरीके हैं जो मैंने स्रोत से अनुकूलित किए हैं।

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

1

यह कार्यक्षमता प्रदान करने वाला एक पुस्तकालय है :

SnakeCaseFormatter::run('CamelCase'); // Output: "camel_case"

1
मुझे लगता है कि आपका मतलब है "मैंने यह कार्यक्षमता प्रदान करने वाला एक पुस्तकालय बनाया है"। सेल्फ प्रमोशन में कुछ भी गलत नहीं है, लेकिन इसे छिपाएं नहीं।
icc97


1

यह छोटे तरीकों में से एक है:

function camel_to_snake($input)
{
    return strtolower(ltrim(preg_replace('/([A-Z])/', '_\\1', $input), '_'));
}

कोड-ओनली उत्तर स्टैकओवरफ़्लो पर कम मूल्य हैं क्योंकि वे हजारों भविष्य के शोधकर्ताओं को शिक्षित / सशक्त बनाने के लिए बहुत कम करते हैं।
मिकमैकुसा

1
@ मिकमैकुसा - भविष्य के हजारों शोधों को एक एक-एक लाइनर में रुचि होगी, और खुद को शिक्षित करेंगे।
टेसन

मुझे खेद है कि आपने वह स्वार्थपूर्ण रुख अपनाया है। आप निश्चित रूप से उस समय में एक स्पष्टीकरण जोड़ सकते थे जो आपको उस घिनौने उत्तर को डिजाइन करने और टाइप करने के लिए ले गया था। आपका उत्तर तीन फ़ंक्शन कॉल करता है, लेकिन अन्य दो में कार्य करते हैं।
मिकमैकुसा

1

रेगेक्स का उपयोग किए बिना डी-कैमेलाइज़ कैसे करें:

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

1
कोड-ओनली उत्तर स्टैकओवरफ़्लो पर कम मूल्य हैं क्योंकि वे भविष्य के शोधकर्ताओं को सशक्त / शिक्षित करने का एक खराब काम करते हैं। स्ट्रिंग में प्रत्येक वर्ण पर 1 से 3 फ़ंक्शन कॉल करना फिर लूप किए जाने के बाद दो और फ़ंक्शन कॉल बहुत भारी-भरकम है। मैं ऐसी खराब अर्थव्यवस्था के साथ समाधान का मनोरंजन नहीं करूंगा।
मिकमैकुसा

यह एक उदाहरण है कि इसे नियमित अभिव्यक्तियों का उपयोग किए बिना कैसे किया जा सकता है, न कि इसका उपयोग उत्पादन में कैसे किया जाना चाहिए, इसलिए मुझे आपकी बात नहीं दिखती है इसके अलावा आप 5y / o उत्तर के बारे में शिकायत करते हैं जिसमें एक अपवोट है और इसके द्वारा देखे जाने की संभावना नहीं है कोई भी शोधकर्ता।
बाल्डर्स

मैं अपना ध्यान सभी पदों पर देता हूं, न कि केवल उच्च पदों वाले या हाल के लोगों पर। मैं शिकायत नहीं कर रहा हूं, मैं अपनी आलोचना कर रहा हूं ताकि कम ज्ञान वाले शोधकर्ता इस उत्तर और अन्य उत्तरों के बीच के अंतर को बेहतर ढंग से समझ सकें। आप अपनी पोस्ट में स्पष्ट कर सकते हैं कि रेगेक्स से बचना महज एक अकादमिक चुनौती थी। उस ने कहा, बेहतर कोडिंग प्रथाओं के साथ इस प्रक्रिया को अधिक कुशल बनाने के तरीके हैं।
मिकमैकुसा

0

Zend Word फिल्टर के फ़िल्टर वर्गों का उपयोग करना आसान है :

<?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 >>> एचटीएमएल

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

एस्ट्रिंग >>> a_string

Some4Numbers234 >>> some4_numbers234

TEST123String >>> test123_string


0

ओपन सोर्स TurboCommons लाइब्रेरी में StringUtils वर्ग के अंदर एक सामान्य उद्देश्य फॉर्मेटकेस () पद्धति है, जो आपको कई स्ट्रिंग केस प्रारूप में बदलने की सुविधा देती है, जैसे CamelCase, UpperCamelCase, LowerCamelbase, snake_case, Title Case और कई और।

https://github.com/edertone/TurboCommons

इसका उपयोग करने के लिए, अपनी परियोजना के लिए चरण फ़ाइल आयात करें और:

use org\turbocommons\src\main\php\utils\StringUtils;

echo StringUtils::formatCase('camelCase', StringUtils::FORMAT_SNAKE_CASE);

// will output 'camel_Case'

0
$str = 'FooBarBaz';

return strtolower(preg_replace('~(?<=\\w)([A-Z])~', '_$1', $str)); // foo_bar_baz

1
कोड-ओनली उत्तर स्टैकओवरफ़्लो पर कम मूल्य हैं क्योंकि वे भविष्य के शोधकर्ताओं को सशक्त / शिक्षित करने का एक खराब काम करते हैं।
मिकमैकुसा

-1

यदि आप इसके साथ शुरू कर सकते हैं:

$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
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.