Wie Pascal zu pascal_case konvertieren?
-
22-09-2019 - |
Frage
Wenn ich:
$string = "PascalCase";
Ich brauche
"pascal_case"
Does PHP bietet eine Funktion für diesen Zweck?
Lösung
Versuchen Sie, diese für Größe:
$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);
}
Ausgabe:
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
Dies implementiert die folgenden Regeln:
- Eine Sequenz mit einem Kleinbuchstaben beginnen müssen von Kleinbuchstaben und Ziffern folgen;
- Eine Sequenz mit einem Großbuchstaben beginnen kann entweder folgen:
- ein oder mehr Großbuchstaben und Ziffern (gefolgt von entweder das Ende der Schnur oder einen Großbuchstaben von einem Kleinbuchstabe oder Ziffer dh den Start der nächsten Sequenz folgte); oder
- eine oder mehrere Kleinbuchstaben und Ziffern.
Andere Tipps
Eine kürzere Lösung: ähnlich wie bei der Redaktion ein mit einem vereinfachten regulären Ausdruck und zur Festsetzung des „nachlaufStrich“ Problem:
$output = strtolower(preg_replace('/(?<!^)[A-Z]/', '_$0', $input));
Beachten Sie, dass Fälle wie SimpleXML
wird simple_x_m_l
unter Verwendung der obigen Lösung umgewandelt werden. Das kann auch eine falsche Verwendung von Kamel Fall Notation in Betracht gezogen werden (korrekter SimpleXml
wäre), anstatt ein Fehler des Algorithmus, da solche Fälle sind immer mehrdeutig - auch durch Großbuchstaben Gruppierung zu einer Zeichenkette (simple_xml
) solcher Algorithmus wird immer in andere scheitern Grenzfälle wie XMLHTMLConverter
oder ein-Buchstaben-Worte in der Nähe von Abkürzungen, etc. Wenn Sie nicht über die (eher selten) Grenzfälle und wollen Griff SimpleXML
richtig nichts ausmachen, können Sie eine wenig komplexe Lösung verwenden:
$output = ltrim(strtolower(preg_replace('/[A-Z]([A-Z](?![a-z]))*/', '_$0', $input)), '_');
Eine kurze Lösung und kann einige schwierige Anwendungsfälle behandeln:
function decamelize($string) {
return strtolower(preg_replace(['/([a-z\d])([A-Z])/', '/([^_])([A-Z][a-z])/'], '$1_$2', $string));
}
Kann alle diese Fälle behandeln:
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
Sie können diese Funktion testen hier: http://syframework.alwaysdata.net/decamelize
Portierte von Rubys String#camelize
und 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);
}
Ein Trick, die oben genannten Lösungen verpaßt haben ist das ‚e‘ Modifikator, die preg_replace
bewirkt, dass der Ersatz-String als PHP-Code bewerten.
Die Symfony Serializer Komponente eine CamelCaseToSnakeCaseNameConverter das hat zwei Methoden normalize()
und denormalize()
. Diese können wie folgt verwendet werden:
$nameConverter = new CamelCaseToSnakeCaseNameConverter();
echo $nameConverter->normalize('camelCase');
// outputs: camel_case
echo $nameConverter->denormalize('snake_case');
// outputs: snakeCase
Die meisten Lösungen hier fühlen sich schwer handed. Hier ist, was ich benutze:
$underscored = strtolower(
preg_replace(
["/([A-Z]+)/", "/_([A-Z]+)([A-Z][a-z])/"],
["_$1", "_$1_$2"],
lcfirst($camelCase)
)
);
"Camelcase" auf "camel_case" umgewandelt
-
lcfirst($camelCase)
wird das erste Zeichen (Vermeidet ‚Camelcase‘ konvertierte Ausgabe beginnen mit einem Unterstrich) senken
-
[A-Z]
findet Großbuchstaben -
+
wird jeden aufeinanderfolgende Großbuchstaben als Wort behandelt (Vermeidet ‚Camelcase‘ zu camel_C_A_S_E umgewandelt werden) - Zweites Muster und Ersatz ist für
ThoseSPECCases
->those_spec_cases
stattthose_speccases
-
strtolower([…])
schaltet die Ausgabe in Kleinbuchstaben
PHP nicht bieten eine für diese afaik in Funktion gebaut, aber hier ist das, was ich
function uncamelize($camel,$splitter="_") {
$camel=preg_replace('/(?!^)[[:upper:]][[:lower:]]/', '$0', preg_replace('/(?!^)[[:upper:]]+/', $splitter.'$0', $camel));
return strtolower($camel);
}
der Splitter kann in dem Funktionsaufruf angegeben werden, so dass Sie es wie so nennen können
$camelized="thisStringIsCamelized";
echo uncamelize($camelized,"_");
//echoes "this_string_is_camelized"
echo uncamelize($camelized,"-");
//echoes "this-string-is-camelized"
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_áááá_őőőő
Wenn Sie eine PHP 5.4 Version suchen und später hier beantworten ist der Code:
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
);
}
Nichts Besonderes an alle, aber einfach und schnell wie die Hölle:
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
"Camelcase" auf "camel_case":
function camelToSnake($camel)
{
$snake = preg_replace('/[A-Z]/', '_$0', $camel);
$snake = strtolower($snake);
$snake = ltrim($snake, '_');
return $snake;
}
oder:
function camelToSnake($camel)
{
$snake = preg_replace_callback('/[A-Z]/', function ($match){
return '_' . strtolower($match[0]);
}, $camel);
return ltrim($snake, '_');
}
Eine Version, die nicht regex nicht verwenden kann, in der Alchitect Quelle gefunden werden:
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);
}
So, hier ist ein Einzeiler:
strtolower(preg_replace('/(?|([a-z\d])([A-Z])|([^\^])([A-Z][a-z]))/', '$1_$2', $string));
danielstjules / Stringy provieds ein Verfahren zum Konvertieren von Zeichenfolge von Camelcase zu snakecase.
s('TestUCase')->underscored(); // 'test_u_case'
Laravel 5.6 bietet eine sehr einfache Möglichkeit, dies zu tun:
/**
* 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;
}
Was es tut: wenn er sieht, dass es zumindest einen Großbuchstaben in der gegebenen Zeichenkette, verwendet es eine positive Vorschau für ein beliebiges Zeichen (.
) zu suchen, gefolgt von einem Großbuchstaben ((?=[A-Z])
). Es ersetzt dann die gefundenen Zeichen mit seinem Wert durch die separactor _
gefolgt.
Der direkte Anschluss von Schienen (minus ihre Sonderbehandlung für :: oder Akronyme) wäre
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, '-', '_'));
}
Zu wissen, PHP, wird dies schneller als die manuelle Analyse, die in anderen hier gegebenen Antworten passiert. Der Nachteil ist, dass Sie nicht als Trennzeichen zwischen Worten, was dem Einsatz wählen haben, aber das war nicht Teil der Frage.
Überprüfen Sie auch die entsprechenden Schienen Quelle Code
Beachten Sie, dass diese für die Verwendung mit ASCII-Identifikatoren vorgesehen ist. Wenn Sie dies mit Zeichen tun, müssen außerhalb des ASCII-Bereichs, verwenden Sie die ‚/ u‘ Modifikator für preg_match
and Verwendung mb_strtolower
.
Hier ist mein Beitrag zu einem sechs Jahre alten Frage mit Gott weiß, wie viele Antworten ...
Es werden alle Wörter in der mitgelieferten Zeichenfolge konvertieren, die in Camelcase zu snakecase sind. Zum Beispiel "SuperSpecialAwesome und FizBuzz καιΚάτιΑκόμα auch" wird umgewandelt werden "super_special_awesome und auch fizz_buzz και_κάτι_ακόμα".
mb_strtolower(
preg_replace_callback(
'/(?<!\b|_)\p{Lu}/u',
function ($a) {
return "_$a[0]";
},
'SuperSpecialAwesome'
)
);
Yii2 haben die andere Funktion das Wort snake_case von Camelcase zu machen.
/**
* 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));
}
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);
}
Es gibt eine Bibliothek bietet diese Funktionalität:
SnakeCaseFormatter::run('CamelCase'); // Output: "camel_case"
Wenn Sie Laravel Framework verwenden, können Sie einfach snake_case () Methode.
$str = 'FooBarBaz';
return strtolower(preg_replace('~(?<=\\w)([A-Z])~', '_$1', $str)); // foo_bar_baz
Dies ist ein kürzeren Wege:
function camel_to_snake($input)
{
return strtolower(ltrim(preg_replace('/([A-Z])/', '_\\1', $input), '_'));
}
Wie de-camelize ohne Regex:
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;
}
Ein edit:
Wie würde ich das tue im Jahr 2019:
function toSnakeCase($str, $glue = '_') {
return preg_replace_callback('/[A-Z]/', function ($matches) use ($glue) {
return $glue . strtolower($matches[0]);
}, $str);
}
Und wenn PHP 7.4 wird freigegeben:
function toSnakeCase($str, $glue = '_') {
return preg_replace_callback('/[A-Z]/', fn($matches) => $glue . strtolower($matches[0]), $str);
}
Kurz Lösung:
$subject = "PascalCase";
echo strtolower(preg_replace('/\B([A-Z])/', '_$1', $subject));
Es ist einfach, die Filter-Klassen des Zend Wort 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 >>> Simple
leicht >>> Leicht
html >>> Html
simple_xml >>> SimpleXML
pdf_load >>> PdfLoad
start_middle_last >>> StartMiddleLast
a_string >>> AString
some4_numbers234 >>> Some4Numbers234
test123_string >>> Test123String
----- ----- camelCaseToUnderscore
Simple >>> simple_test
leicht >>> einfach
HTML >>> html
SimpleXML >>> simple_xml
PDFLoad >>> pdf_load
startMIDDLELast >>> start_middle_last
AString >>> a_string
Some4Numbers234 >>> some4_numbers234
TEST123String >>> test123_string
Die schlechteste Antwort auf hier war so nah, der Beste zu sein (ein Framework verwenden). NO dies nicht tun, nur einen Blick auf den Quellcode. zu sehen, was ein gut etabliertes Framework verwendet ein weitaus zuverlässigen Ansatz wäre (bewährten). Das Zend Framework hat einige Wortfilter, die Ihre Bedürfnisse anzupassen. Quelle .
Hier ist ein paar Methoden, die ich von der Quelle angepasst.
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");
Die Open-Source-TurboCommons Bibliothek enthält einen Mehrzweck formatCase () -Methode in der StringUtils-Klasse, die Sie eine Zeichenfolge zu vielen häufigeren Fall Formate konvertieren kann, wie Camelcase, Uppercamelcase, LowerCamelCase, snake_case, Titel Case, und viele mehr.
https://github.com/edertone/TurboCommons
Um es zu verwenden, importieren Sie die phar Datei zu Ihrem Projekt und:
use org\turbocommons\src\main\php\utils\StringUtils;
echo StringUtils::formatCase('camelCase', StringUtils::FORMAT_SNAKE_CASE);
// will output 'camel_Case'
Ich hatte ein ähnliches Problem, aber konnte keine Antwort finden, dass befriedigt, wie Camelcase zu snake_case konvertieren, während die Vermeidung doppelter oder redundanter Unterstrichen für Namen mit Unterstrichen _
oder alle Kappen Abkürzungen.
Th Problem ist wie folgt:
CamelCaseClass => camel_case_class
ClassName_WithUnderscores => class_name_with_underscore
FAQ => faq
Die Lösung, die ich geschrieben habe, ist eine einfache zwei Funktionen aufrufen, Klein-und suchen und für aufeinanderfolgende Klein-Großbuchstaben ersetzt werden:
strtolower(preg_replace("/([a-z])([A-Z])/", "$1_$2", $name));
Wenn Sie könnte beginnen mit:
$string = 'Camel_Case'; // underscore or any other separator...
Dann könnte man auf jeden Fall umbauen mit:
$pascal = str_replace("_", "", $string);
$snake = strtolower($string);
oder eine beliebige andere Fälle:
$capitalized = str_replace("_", " ", $string); // Camel Case
$constant = strtoupper($string); // CAMEL_CASE
$train = str_replace("_", "-", $snake); // camel-case