Wie würde ich vorgehen, um das Wort zu teilen:
oneTwoThreeFour
in ein Array, damit ich bekommen kann:
one Two Three Four
mit preg_match
?
Ich habe es satt, aber es gibt nur das ganze Wort
$words = preg_match("/[a-zA-Z]*(?:[a-z][a-zA-Z]*[A-Z]|[A-Z][a-zA-Z]*[a-z])[a-zA-Z]*\b/", $string, $matches)`;
php
regex
string
preg-match
Auf Wiedersehen
quelle
quelle
Antworten:
Sie können auch verwenden
preg_match_all
als:preg_match_all('/((?:^|[A-Z])[a-z]+)/',$str,$matches);
Erläuterung:
quelle
HTMLParser
funktioniert: stackoverflow.com/a/6572999/1697320 .'/(?:^|[A-Z])[a-z]+/'
würde ausreichen, um ein Array (anstelle von zwei) zu erzeugen. Dies liegt daran, dasspreg_match_all()
automatisch alle Instanzen des Spiels erfasst werden, ohne dass Sie dies speziell festlegen müssen.Sie können verwenden
preg_split
als:$arr = preg_split('/(?=[A-Z])/',$str);
Sehen Sie es
Grundsätzlich teile ich die Eingabezeichenfolge kurz vor dem Großbuchstaben. Die verwendete Regex
(?=[A-Z])
entspricht dem Punkt unmittelbar vor einem Großbuchstaben.quelle
Ich weiß, dass dies eine alte Frage mit einer akzeptierten Antwort ist, aber meiner Meinung nach gibt es eine bessere Lösung:
<?php // test.php Rev:20140412_0800 $ccWord = 'NewNASAModule'; $re = '/(?#! splitCamelCase Rev:20140412) # Split camelCase "words". Two global alternatives. Either g1of2: (?<=[a-z]) # Position is after a lowercase, (?=[A-Z]) # and before an uppercase letter. | (?<=[A-Z]) # Or g2of2; Position is after uppercase, (?=[A-Z][a-z]) # and before upper-then-lower case. /x'; $a = preg_split($re, $ccWord); $count = count($a); for ($i = 0; $i < $count; ++$i) { printf("Word %d of %d = \"%s\"\n", $i + 1, $count, $a[$i]); } ?>
Beachten Sie, dass dieser reguläre Ausdruck (wie die
'/(?=[A-Z])/'
Lösung von codaddict - die wie ein Zauber für wohlgeformte camelCase-Wörter funktioniert) nur einer Position innerhalb der Zeichenfolge entspricht und überhaupt keinen Text verbraucht. Diese Lösung hat den zusätzlichen Vorteil, dass sie auch für nicht so gut geformte Pseudo-Camelcase-Wörter wie:StartsWithCap
und: korrekt funktionierthasConsecutiveCAPS
.Eingang:
oneTwoThreeFour
StartsWithCap
hasConsecutiveCAPS
NewNASAModule
Ausgabe:
Word 1 of 4 = "one"
Word 2 of 4 = "Two"
Word 3 of 4 = "Three"
Word 4 of 4 = "Four"
Word 1 of 3 = "Starts"
Word 2 of 3 = "With"
Word 3 of 3 = "Cap"
Word 1 of 3 = "has"
Word 2 of 3 = "Consecutive"
Word 3 of 3 = "CAPS"
Word 1 of 3 = "New"
Word 2 of 3 = "NASA"
Word 3 of 3 = "Module"
Bearbeitet: 2014-04-12: Regex- , Skript- und Testdaten wurden geändert, um den
"NewNASAModule"
Fall korrekt aufzuteilen: case (als Antwort auf den Kommentar von rr).quelle
NewNASAModule
(Ausgaben :[New, NASAModule]
; Ich würde erwarten[New, NASA, Module]
)NewNASAModule
richtig: RegEx, um camelCase oder TitleCase (erweitert) zuDie Antwort von ridgerunner funktioniert zwar hervorragend, scheint jedoch nicht mit All-Caps-Teilzeichenfolgen zu funktionieren, die in der Mitte des Satzes erscheinen. Ich benutze folgendes und es scheint in Ordnung damit umzugehen:
function splitCamelCase($input) { return preg_split( '/(^[^A-Z]+|[A-Z][^A-Z]+)/', $input, -1, /* no limit for replacement count */ PREG_SPLIT_NO_EMPTY /*don't return empty elements*/ | PREG_SPLIT_DELIM_CAPTURE /*don't strip anything from output array*/ ); }
Einige Testfälle:
assert(splitCamelCase('lowHigh') == ['low', 'High']); assert(splitCamelCase('WarriorPrincess') == ['Warrior', 'Princess']); assert(splitCamelCase('SupportSEELE') == ['Support', 'SEELE']); assert(splitCamelCase('LaunchFLEIAModule') == ['Launch', 'FLEIA', 'Module']); assert(splitCamelCase('anotherNASATrip') == ['another', 'NASA', 'Trip']);
quelle
Eine funktionalisierte Version von @ ridgerunners Antwort.
/** * Converts camelCase string to have spaces between each. * @param $camelCaseString * @return string */ function fromCamelCase($camelCaseString) { $re = '/(?<=[a-z])(?=[A-Z])/x'; $a = preg_split($re, $camelCaseString); return join($a, " " ); }
quelle
$string = preg_replace( '/([a-z0-9])([A-Z])/', "$1 $2", $string );
Der Trick ist ein wiederholbares Muster. $ 1 $ 2 $ 1 $ 2 oder niedriger UPPERlower UPPERlower usw. "Hallo Welt" entspricht HelloWorld als $ 2 $ 1 $ 2 $ 1 oder erneut als "Hallo Welt". Dann können Sie das erste Wort in Kleinbuchstaben schreiben oder im Leerzeichen explodieren lassen oder ein _ oder ein anderes Zeichen verwenden, um sie getrennt zu halten.
Kurz und einfach.
quelle
Bei der Ermittlung des besten Musters für Ihr Projekt müssen Sie die folgenden Musterfaktoren berücksichtigen:
Die oben genannten Faktoren liegen zufällig auch in der hierarchischen Reihenfolge, die zu befolgen versucht. Mit anderen Worten, es macht für mich wenig Sinn, 2, 3 oder 4 zu priorisieren, wenn 1 die Anforderungen nicht ganz erfüllt. Die Lesbarkeit steht für mich ganz unten auf der Liste, da ich in den meisten Fällen der Syntax folgen kann.
Erfassungsgruppen und Lookarounds wirken sich häufig auf die Mustereffizienz aus. Die Wahrheit ist, dass Sie nicht über die Effizienz hinarbeiten müssen, es sei denn, Sie führen diesen regulären Ausdruck für Tausende von Eingabezeichenfolgen aus. Es ist vielleicht wichtiger, sich auf die Lesbarkeit von Mustern zu konzentrieren, die mit der Kürze des Musters verbunden sein können.
Einige der folgenden Muster erfordern eine zusätzliche Behandlung / Kennzeichnung durch ihre
preg_
Funktion, aber hier sind einige Mustervergleiche, die auf der Beispieleingabe des OP basieren:preg_split()
Muster:/^[^A-Z]+\K|[A-Z][^A-Z]+\K/
(21 Schritte)/(^[^A-Z]+|[A-Z][^A-Z]+)/
(26 Schritte)/[^A-Z]+\K(?=[A-Z])/
(43 Schritte)/(?=[A-Z])/
(50 Schritte)/(?=[A-Z]+)/
(50 Schritte)/([a-z]{1})[A-Z]{1}/
(53 Schritte)/([a-z0-9])([A-Z])/
(68 Schritte)/(?<=[a-z])(?=[A-Z])/x
(94 Schritte) ... für die Aufzeichnung ist dasx
nutzlos./(?<=[a-z])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])/
(134 Schritte)preg_match_all()
Muster:/[A-Z]?[a-z]+/
(14 Schritte)/((?:^|[A-Z])[a-z]+)/
(35 Schritte)Ich werde darauf hinweisen, dass es einen subtilen Unterschied zwischen der Ausgabe von
preg_match_all()
und gibtpreg_split()
.preg_match_all()
gibt ein zweidimensionales Array aus, mit anderen Worten, alle Fullstring-Übereinstimmungen befinden sich im[0]
Subarray; Wenn eine Erfassungsgruppe verwendet wird, befinden sich diese[1]
Teilzeichenfolgen im Subarray. Andererseits gibtpreg_split()
nur ein eindimensionales Array aus und bietet daher einen weniger aufgeblähten und direkteren Pfad zur gewünschten Ausgabe.Einige der Muster sind unzureichend, wenn es sich um camelCase-Zeichenfolgen handelt, die einen ALLCAPS / Akronym-Teilstring enthalten. Wenn dies ein Randfall ist, der in Ihrem Projekt möglich ist, ist es logisch, nur Muster zu berücksichtigen, die diese Fälle korrekt behandeln. Ich werde keine TitleCase-Eingabezeichenfolgen testen, da dies zu weit von der Frage entfernt ist.
Neue erweiterte Batterie von Teststrings:
Geeignete
preg_split()
Muster:/[a-z]+\K|(?=[A-Z][a-z]+)/
(149 Schritte) * Ich musste verwenden,[a-z]
damit die Demo richtig zählt/(?<=[a-z])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])/
(547 Schritte)Geeignetes
preg_match_all()
Muster:/[A-Z]?[a-z]+|[A-Z]+(?=[A-Z][a-z]|$)/
(75 Schritte)Schließlich meine Empfehlungen basierend auf meinen Musterprinzipien / Faktorhierarchie. I auch empfehlen
preg_split()
überpreg_match_all()
(trotz der Muster weniger Schritten) als eine Angelegenheit von Unmittelbarkeit auf die gewünschte Ausgabestruktur. (Natürlich wählen Sie, was Sie möchten)Code: ( Demo )
$noAcronyms = 'oneTwoThreeFour'; var_export(preg_split('~^[^A-Z]+\K|[A-Z][^A-Z]+\K~', $noAcronyms, 0, PREG_SPLIT_NO_EMPTY)); echo "\n---\n"; var_export(preg_match_all('~[A-Z]?[^A-Z]+~', $noAcronyms, $out) ? $out[0] : []);
Code: ( Demo )
$withAcronyms = 'newNASAModule'; var_export(preg_split('~[^A-Z]+\K|(?=[A-Z][^A-Z]+)~', $withAcronyms, 0, PREG_SPLIT_NO_EMPTY)); echo "\n---\n"; var_export(preg_match_all('~[A-Z]?[^A-Z]+|[A-Z]+(?=[A-Z][^A-Z]|$)~', $withAcronyms, $out) ? $out[0] : []);
quelle
Ich habe den Code von Cool Ridgerunner (oben) genommen und daraus eine Funktion gemacht:
echo deliciousCamelcase('NewNASAModule'); function deliciousCamelcase($str) { $formattedStr = ''; $re = '/ (?<=[a-z]) (?=[A-Z]) | (?<=[A-Z]) (?=[A-Z][a-z]) /x'; $a = preg_split($re, $str); $formattedStr = implode(' ', $a); return $formattedStr; }
Dies wird zurückkehren:
New NASA Module
quelle
Eine andere Option ist das Matching.
/[A-Z]?[a-z]+/
Wenn Sie wissen, dass Ihre Eingabe das richtige Format hat, sollte sie gut funktionieren.[A-Z]?
würde mit einem Großbuchstaben (oder nichts) übereinstimmen.[a-z]+
würde dann alle folgenden Kleinbuchstaben bis zur nächsten Übereinstimmung abgleichen.Arbeitsbeispiel: https://regex101.com/r/kNZfEI/1
quelle
Sie können auf einem "Gleiten" von Kleinbuchstaben zu Großbuchstaben auf folgende Weise aufteilen:
$parts = preg_split('/([a-z]{1})[A-Z]{1}/', $string, -1, PREG_SPLIT_DELIM_CAPTURE); //PREG_SPLIT_DELIM_CAPTURE to also return bracketed things var_dump($parts);
Ärgerlicherweise müssen Sie dann die Wörter aus jedem entsprechenden Elementpaar in $ parts neu erstellen
Hoffe das hilft
quelle
Zunächst einmal Codaddict, danke für dein Muster, es hat sehr geholfen!
Ich brauchte eine Lösung, die funktioniert, falls eine Präposition 'a' existiert:
zB thisIsACamelcaseSentence.
Ich fand die Lösung in einem zweistufigen preg_match und erstellte eine Funktion mit einigen Optionen:
/* * input: 'thisIsACamelCaseSentence' output: 'This Is A Camel Case Sentence' * options $case: 'allUppercase'[default] >> 'This Is A Camel Case Sentence' * 'allLowerCase' >> 'this is a camel case sentence' * 'firstUpperCase' >> 'This is a camel case sentence' * @return: string */ function camelCaseToWords($string, $case = null){ isset($case) ? $case = $case : $case = 'allUpperCase'; // Find first occurances of two capitals preg_match_all('/((?:^|[A-Z])[A-Z]{1})/',$string, $twoCapitals); // Split them with the 'zzzzzz' string. e.g. 'AZ' turns into 'AzzzzzzZ' foreach($twoCapitals[0] as $match){ $firstCapital = $match[0]; $lastCapital = $match[1]; $temp = $firstCapital.'zzzzzz'.$lastCapital; $string = str_replace($match, $temp, $string); } // Now split words preg_match_all('/((?:^|[A-Z])[a-z]+)/', $string, $words); $output = ""; $i = 0; foreach($words[0] as $word){ switch($case){ case 'allUpperCase': $word = ucfirst($word); break; case 'allLowerCase': $word = strtolower($word); break; case 'firstUpperCase': ($i == 0) ? $word = ucfirst($word) : $word = strtolower($word); break; } // remove te 'zzzzzz' from a word if it has $word = str_replace('zzzzzz','', $word); $output .= $word." "; $i++; } return $output; }
Fühlen Sie sich frei, es zu benutzen, und falls es einen "einfacheren" Weg gibt, dies in einem Schritt zu tun, kommentieren Sie bitte!
quelle
Volle Funktion basierend auf @codaddict Antwort:
function splitCamelCase($str) { $splitCamelArray = preg_split('/(?=[A-Z])/', $str); return ucwords(implode($splitCamelArray, ' ')); }
quelle