PascalCaseをpascal_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. 大文字で始まるシーケンスの後には、次のいずれかを続けることができます。
    • 1つ以上の大文字と数字(文字列の末尾または大文字の後に小文字または数字が続く、つまり次のシーケンスの開始)。または
    • 1つ以上の小文字または数字。

9
これはCamelCased文字列(openfrogが尋ねたように)で機能しますが、たとえば「r_id」(すでに「アンダースコア」)の入力文字列とともに使用すると、プレフィックス(「r_」)が削除されます。良い解決策ですが、間違いなく普遍的ではありません。
マーティン

1
文字列がすべて大文字の文字列と一致するかどうかを確認しているのはなぜですか?(すべての文字ではなく)最初の文字だけを小文字に変換する利点は何ですか?
ジョシュ

1
これらすべてのユースケースも処理できる、より簡潔なソリューション:stackoverflow.com/a/35719689/4328383
Syone

156

より短い解決策:正規化表現を単純化し、「末尾のアンダースコア」の問題を修正したエディターのものと同様です。

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

PHPデモ | 正規表現のデモ


のような場合は、上記のソリューションSimpleXMLsimple_x_m_l使用するように変換されます。SimpleXml大文字の文字を1つの文字列にグループ化しても(simple_xml)このようなアルゴリズムは常に他のエッジケースで失敗するので、そのようなケースは常にあいまいであるため、アルゴリズムのバグではなく、キャメルケース表記の誤った使用(正解は)と見なすこともできます。のように、XMLHTMLConverterまたは略語の近くの1文字の単語。(かなりまれな)エッジケースを気にせずSimpleXML、正しく処理したい場合は、もう少し複雑なソリューションを使用できます。

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

PHPデモ | 正規表現のデモ


どのテストケースを修正したかを詳しく説明しているクレタスの回答にコメントしてください。
マイクB

3
彼の解決策が間違った結果をもたらすと言っているのではありません。彼の解決策は非常に複雑で効果がありません。
JanJakeš2013年

1
はい、受け入れの答えは間違いなく失敗です。Janのソリューションは素晴らしいです!余談ですが、この質問(またはわずかなバリエーション)は、PHP開発者にとって私のお気に入りのコーディングテストだと思います。これは、最初のフィルタリングを行うための優れた方法です。:-)
JamesG、2015

このソリューションで使用される正規表現は、はるかに完全が見つかりました:stackoverflow.com/questions/2559759/...
thoroc

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この正規表現のどの部分がわからないのですか?
Syone

ええと、キャメルケース以外の文字列を小文字にするのは副作用です。文字列がキャメルケース形式でない場合は、元の文字列を返す必要があります。「simple_Text」を送信すると、Fail:simple_Test => simple_Test [simple_test]が発生します。小文字の文字列は、元の文字列のみが実際のキャメルケース文字列の場合にのみ作成する必要があります。についてどう思いますか?
guido

24

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

上記のソリューションで見逃していたトリックの1つはpreg_replace、置換文字列をPHPコードとして評価する「e」修飾子です。


10
eフラグpreg_replaceは、PHP 5.5で廃止されています。
cdmckay

ところで、これらはRubyにもありませんが、Railsのインフレクタライブラリにあります-ラクダとアンダースコア。api.rubyonrails.org/classes/ActiveSupport/Inflector.html
mahemoff

2
これは「ThisIsATest」では失敗します。2つの連続した大文字をサポートしていないようです。
OnaBai 2013

注:lcfirstを使用して最初の文字を小文字にすると、^|またはは不要になりstrlenます。
Benubird 2013

廃止せずにデカメル化します:gist.github.com/scones/e09c30e696246fda14578bcf8ab4910a
スコーン

23

symfonyのシリアライザコンポーネントがありCamelCaseToSnakeCaseNameConverter 2つのメソッドを持っているnormalize()としますdenormalize()。これらは次のように使用できます。

$nameConverter = new CamelCaseToSnakeCaseNameConverter();

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

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

1
注意してください! Symfony Serializer Componentの現在のバージョン3.2の$nameConverter->normalize('CamelCase')出力_camel_case
spackmat 2017

21

ここでのほとんどの解決策は、強引に感じます。これが私が使うものです:

$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に変換されるのを避けます)
  • 2番目のパターンと置換はThoseSPECCases->のthose_spec_cases代わりにthose_speccases
  • strtolower([…]) 出力を小文字に変換します

3
ただし、CamelCasedが_camel_casedに変わります。
acme 2013

1
これはすばらしいことです。char1から始まるsubstrを追加するだけで、この問題を回避できます。
オッドマン

4
素晴らしい!lcfirst$ camelCaseに関数を追加するだけです
Edakos

受け入れられた回答は次のように処理します:TestUPSClassをtest_ups_classに変換しますが、これによりtest_u_p_s_classに変換されます。
Mazzy

allcapsの最初の "word"で始まる入力文字列は、ucfirst()呼び出しのため、このソリューションによって予期せず分割されます。 デモUSADollarSymbolなる正規表現で入力文字列を2回パスする必要があるため、このソリューションはお勧めしません-洗練されていないパターンの兆候です。u_sa_dollar_symbol
mickmackusa

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」では失敗します。2つの連続した大文字をサポートしていないようです。
OnaBai 2013

2番目の交換では何も行われないため、確かに何かを忘れました。これとは別に、とのユニコード互換性mb_strtolowerとの/uオプションを簡単に作成できますpreg_replace
bodo 2015年

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_áááá_őőőő

このコードは入力がorのcamelCase代わりであると想定しているため、文字列の大文字小文字がわからない場合は、最初に確認することをお勧めします。後者は大文字の場合、アンダースコアが追加されます。underscore_Casedash-Case

cletusから受け入れられた答えは、あまりにも複雑すぎるimhoであり、ラテン文字でのみ機能します。私はそれが本当に悪い解決策だと思って、なぜそれがまったく受け入れられたのか疑問に思います。変換TEST123Stringにはtest123_string必ずしも有効では必須ではありません。この方法では情報が失われず、逆方向の変換によって、最初とまったく同じ文字列が得られるため、代わりに単純にして分離ABCcccしました。他の方法でそれを実行したい場合でも、正規表現の専門家でない場合は、肯定的な後読み付きの正規表現、または後読みなしの2つの正規表現を書くのは比較的簡単です。間で決定する言及しない部分文字列にそれを分割する必要はありませんし、どこだけ使用して、完全に罰金だろうが。a_b_ccccab_cccc(?<!^)\p{Lu}\p{Ll}|(?<=\p{Ll})\p{Lu}strtolowerlcfirststrtolower


Stackoverflowでは、コードのみの回答は価値が低く、何千人もの将来の研究者を教育/支援することはほとんどありません。
mickmackusa

@mickmackusa SOからコーディングする方法を研究者が学ぶ場合、深刻な問題が発生します...
inf3rno

システムから個人的な攻撃を受けたので、答えを改善してください。あなたのソリューションがどのように機能するか、そしてなぜそれらのパターン修飾子を使用しているのかを知っていると仮定すると、私はこのコミュニティからの知識を差し控える正当な理由はないと思います。より卑劣な応答を残すことを検討している場合は、私が気にしないことを保証します。あなたがコメントをとっている間に、あなたはあなたの答えを完了したかもしれません、私たちは私たちのコメントを削除したかもしれません、そして私はこのサイトを助けるためにどこかに行ったかもしれません。
mickmackusa

もちろん、私には8票の投稿を削除する権限はありません。必要に応じて回答を削除することもできますが、不要なパターン修飾子を削除して説明を追加するだけで簡単に改善することはそれほど難しくありません。個人攻撃は私に影響を与えません。
mickmackusa

@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は、sms_sentの「SmsSent」を生成します。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++少し速くすることもできます;)
Mathieu Amiot

Stackoverflowでは、コードのみの回答は価値が低く、何千人もの将来の研究者を教育/支援することはほとんどありません。
mickmackusa

4

「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
thexpand

3

正規表現を使用しないバージョンは、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);
}

1
これは正規表現なしの生活です:-)
2010年

4
ええ、ええ。RegExには間違いなく利点があります。:)生の速度はそれらの1つではありません。
Darrell Brogdon、2010年

何らかの理由でこれでいくつかの面白い結果を得ました
mr1031011

「CamelCaseTestAAATestAA」という文字列に基づいて機能しません。「camel_case_test_a_a_a_test_a_a」、「:camel_case_test_aest」...
Sybio

3

だからここにワンライナーがあります:

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

いいですが、最初の外観のみを変換するのでg、この正規表現に修飾子を追加することをお勧めします。
acme 2015

@acme、私はそれなしgでそれを使用し、それは私にとってはうまくいきます。
シールト

私の場合、何らかの理由でを追加する必要がありましたg。しかし、テストしたフレーズを思い出せません。
acme 2015

3

danielstjules / Stringyは、文字列をキャメルケースからスネークケースに変換するメソッドを提供します。

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

3

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

機能:指定された文字列に少なくとも1つの大文字が含まれている場合は、ポジティブルックアヘッドを使用して、任意の文字(.)の後に大文字()が続き(?=[A-Z])ます。次に、見つかった文字をその値で置き換え、その後に区切り文字を続け_ます。


この関数はsnake_case()と呼ばれるようになり、グローバル名前空間に存在します。
Wotuu

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を知っているので、これは、ここで示されている他の回答で発生している手動の解析よりも速くなります。欠点は、単語間の区切り文字として何を使用するかを選択できないことですが、それは問題の一部ではありませんでした。

関連するRailsのソースコードも確認してください

これは、ASCII識別子での使用を目的としています。ASCII範囲外の文字でこれを行う必要がある場合は、との '/ u'修飾子をpreg_match使用しますmb_strtolower


必要な文字を含むパラメータを追加するだけで、可能です。
Fleshgrinder 2014年

2

これは、6歳の質問に対する私の貢献です。

キャメルケースにある指定された文字列のすべての単語をスネークケースに変換します。たとえば、「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から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));
    }


2

私は同様の問題を抱えていましたが、CamelCaseをsnake_caseに変換する方法を満たす答えを見つけることができませんでした_

この問題は次のとおりです。

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

私が書いた解決策は、小文字と検索、そして連続した小文字と大文字の置換という単純な2つの関数呼び出しです。

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

これは、これまでで最も簡潔で有用なソリューションIMOです。
Mr.Shan0

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])を使用して文字に直接アクセスできます。これにより、コードが長くなりますが、配列との間の変換による大きなオーバーヘッドが回避されます。
bodo 2015年

コードのみの回答は、StackOverflowにとって価値が低く、将来の研究者を支援/教育する上で不十分です。あなたの解決策は、正規表現の恵みを避けながら、非常に強引で複雑です。すべての文字で分割し、複数の反復関数呼び出しを行っています。空の文字列を接着剤として指定する必要はありません。優雅さ、読みやすさ、およびn個の不要な関数呼び出しがないため、プロジェクトの1つではこのソリューションを利用しません。
mickmackusa

1

ここでの最悪の答えは最高であることに非常に近かった(フレームワークを使用)。いいえ、ソースコードを見てください。十分に確立されたフレームワークが何を使用しているかを確認することは、はるかに信頼できるアプローチです(試してテスト済み)。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");

1

この機能を提供するライブラリがあります:

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

1
「私はこの機能を提供するライブラリを作成しました」という意味だと思います。セルフプロモーションに問題はありませんが、非表示にしないでください。
icc97 2017年


1

これは短い方法の1つです。

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

Stackoverflowでは、コードのみの回答は価値が低く、何千人もの将来の研究者を教育/支援することはほとんどありません。
mickmackusa

1
@mickmackusa-何千もの将来の研究は、エレガントなワンライナーに興味があり、自分自身を教育するでしょう。
テソン

そんなわがままな立場をとってごめんなさい。そのぎこちない返信をデザインして入力するのにかかった時間に、説明を追加できたはずです。あなたの答えは3つの関数呼び出しを行いますが、他の人は2つでタスクを実行します。
mickmackusa

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
コードのみの回答は、StackOverflowにとって価値が低く、将来の研究者を支援/教育する上で不十分です。文字列内のすべての文字に対して1〜3回の関数呼び出しを行うと、ループが完了した後にさらに2回の関数呼び出しが発生します。私はそのような貧しい経済での解決策を楽しまないでしょう。
mickmackusa

これは、正規表現を使用せずにそれを実行する方法の例であり、本番環境での使用方法ではありません。そのため、1つの賛成票があり、見られそうにない5年の回答について文句を言うこと以外に、あなたのポイントはわかりません。すべての研究者。
はげ頭

私は非常に賛成の投稿や最近の投稿だけでなく、すべての投稿に注意を払っています。私は文句を言うのではなく、知識が少ない研究者がこの答えと他の答えの違いをよりよく理解できるように私の批評を提供しています。投稿で、正規表現を回避することは単なる学問的な課題であると説明できたでしょう。とはいえ、より良いコーディング方法でこのプロセスをより効率的にする方法はいくつかあります。
mickmackusa

0

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


0

オープンソースの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'

0
$str = 'FooBarBaz';

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

1
コードのみの回答は、StackOverflowにとって価値が低く、将来の研究者を支援/教育する上で不十分です。
mickmackusa

-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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.