| | | | |
| |||||||
| PHP-Fortgeschrittene Arbeiten mit PHP ohne Einschränkungen |
|
| | LinkBack | Themen-Optionen | Thema bewerten |
| | |
| Erfahrener Benutzer Registriert seit: 21.07.2003
Beiträge: 340
PHP-Kenntnisse: Fortgeschritten ![]() | Hallo zusammen,... Ich möchte einen String splitten, ähnlich dem Verhalten des Parameterparsing einer Linux-Shell: Ein oder mehrere Vorkommen von Whitespace trennen die einzelnen Substrings. Es sei denn, das Whitespace-Zeichen ist escaped oder der Bereich, in dem es vorkommt, steht in einfachen oder doppelten Anführungszeichen. Escaping von Anführungszeichen soll auch beachtet werden. Ein Beispiel... Input: Code: a 'b' "c d" e"\" f" ' g" ' '\'h' i\ j k" l"m n"\"" Code: Array
(
[0] => a
[1] => 'b'
[2] => "c d"
[3] => e"\" f"
[4] => ' g" '
[5] => '\'h'
[6] => i\ j
[7] => k" l"m
[8] => n"\""
)
PHP-Code: Also hab ich folgendes gebastelt: PHP-Code: Code: Array
(
[0] => a
[1] => 'b'
[2] => "c d"
[3] => e"\"
[4] => f"
[5] => ' g" '
[6] => '\'
[7] => i\
[8] => j
[9] => k"
[10] => l"m
[11] => n"\""
)
Also... weiß jemand wie ich Escaping in den RegExp einbaue? ![]() Oder hat vielleicht sonst wer einen Vorschlag wie man das besser machen könnte? Schönen Gruß Simbo
__________________ simbo.de Geändert von Simbo (31.03.2011 um 16:05 Uhr). |
| | |
| | |
| PHP Code Flüsterer Registriert seit: 21.08.2005 Beiträge: 4682 PHP-Kenntnisse: Fortgeschritten | |
| | |
| moderatives Dielektrikum Registriert seit: 21.05.2008
Beiträge: 35.987
PHP-Kenntnisse: Fortgeschritten ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() | Nicht ganz sicher, ob das schon alle Escapesituationen abdeckt. Aber etwa so gehts: PHP-Code:
__________________ -- One pixel is still too big. Please make it smaller. ASAP. Initiative Mittelstand. Die wichtigste Gestaltungsregel im Screendesign ist Pi mal Daumen des Arbeitgebers. -- |
| | |
| | |
| Erfahrener Benutzer Registriert seit: 21.07.2003
Beiträge: 340
PHP-Kenntnisse: Fortgeschritten ![]() | Super nikosch, das hilft mir schon mal sehr weiter. ![]() Ich hab das jetzt mal insofern umgebaut, dass alle Zeichen außer den jeweiligen Anführungszeichen und Escapezeichen beachtet werden. Das funktioniert bei meinem Teststring fast perfekt. Manko: Falls ein in Anführungszeichen stehender Bereich nicht wieder durch das jeweilige Anführungszeichen geschlossen wird, soll er bis zum Ende des Strings gelesen werden. PHP-Code: Code: Array
(
[0] => a
[1] => 'b'
[2] => "c
d"
[3] => e"\" f"
[4] => ' gæ" '
[5] => '\'h'
[6] => i\ j
[7] => k" l"m
[8] => n"\"" a"
[9] => öd
)
Code: [8] => n"\""
[9] => a" öd
Denkt ihr, es lohnt sich überhaupt, das ganze als RegExp zu bauen oder sollte ich besser bei der oben beschriebenen Methode bleiben? Die macht ja auch nichts anderes als jedes Zeichen zu betrachten. Wäre die RegExp-Methode von der Performance her wirklich besser? [edit2] nochmal überarbeitet... immer noch fehlerbehaftet... PHP-Code:
__________________ simbo.de Geändert von Simbo (31.03.2011 um 20:45 Uhr). |
| | |
| | |
| Erfahrener Benutzer Registriert seit: 14.06.2009
Beiträge: 1.731
PHP-Kenntnisse: Fortgeschritten ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() | Kommentare zu Qualität oder Performance kann ich leider keine abgeben. Ich habe kurz gebastelt, und der Code lief überraschenderweise beim ersten Ausführen, weshalb ich nicht zu sehr über mögliche Fehler nachgedacht habe. Lasse den einfach mal da, auch wenn er vielleicht nicht benötigt wird. Code: <?php
function getArgsArray($input)
{
$args = array();
$argBuffer = '';
$isInString = false;
$isInEscapeSequence = false;
$activeStringDelimiter = '';
$inputLength = mb_strlen($input);
for ($i = 0; $i < $inputLength; $i++) {
$activeChar = mb_substr($input, $i, 1);
switch (true) {
// Space
case 1 === preg_match('/ /', $activeChar):
if ($isInString) {
$argBuffer .= $activeChar;
} else if ($isInEscapeSequence) {
$isInEscapeSequence = false;
$argBuffer .= $activeChar;
} else {
// Complete argument read,
// push buffer to list (if there is content),
// flush buffer
if ($argBuffer !== '') {
$args[] = $argBuffer;
$argBuffer = '';
}
}
break;
// String delimiter
case 1 === preg_match('/[\'"]/', $activeChar):
if ($isInEscapeSequence) {
$isInEscapeSequence = false;
$argBuffer .= $activeChar;
} else if ($isInString) {
if ($activeStringDelimiter === $activeChar) {
$isInString = false;
}
$argBuffer .= $activeChar;
} else {
$isInString = true;
$activeStringDelimiter = $activeChar;
$argBuffer .= $activeChar;
}
break;
// Escape char
case 1 === preg_match('/\x5C/', $activeChar):
if ($isInEscapeSequence) {
$isInEscapeSequence = false;
$argBuffer .= $activeChar;
} else {
$isInEscapeSequence = true;
$argBuffer .= $activeChar;
}
break;
// Other char
default:
if ($isInEscapeSequence) {
$isInEscapeSequence = false;
$argBuffer .= $activeChar;
} else {
$argBuffer .= $activeChar;
}
break;
}
}
if ($argBuffer !== '') {
$args[] = $argBuffer;
}
return $args;
}
$test = <<<'EOT'
a 'b' "c d" e"\" f" ' g" ' '\'h' i\ j k" l"m n"\""
EOT;
$args = getArgsArray($test);
header('content-type: text/plain');
print_r($args);
|
| | |
| | |
| moderatives Dielektrikum Registriert seit: 21.05.2008
Beiträge: 35.987
PHP-Kenntnisse: Fortgeschritten ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() | Zeichenweise ist immer besser IMHO, allerdings sind die Problematiken rund um Multibytestrings immer etwas schwer einzuschätzen.
__________________ -- One pixel is still too big. Please make it smaller. ASAP. Initiative Mittelstand. Die wichtigste Gestaltungsregel im Screendesign ist Pi mal Daumen des Arbeitgebers. -- |
| | |
| | |
| Erfahrener Benutzer Registriert seit: 14.06.2009
Beiträge: 1.731
PHP-Kenntnisse: Fortgeschritten ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() | Code: $inputLength = mb_strlen($input);
for ($i = 0; $i < $inputLength; $i++) {
$activeChar = mb_substr($input, $i, 1);
Man müsste mal in sich gehen und darüber nachdenken, ob hier nicht byte-weises Vorgehen (also die normalen Stringfunktionen) ausreicht. Ich gehe stark davon aus, dass es ausreichen wird, da alle entscheidenden Zeichen ASCII sind. Geändert von mermshaus (31.03.2011 um 21:54 Uhr). |
| | |
| | |||||
| Erfahrener Benutzer | Zitat:
Zitat:
Zitat:
Zitat:
PHP-Code: Die andere Variante macht fast das Gleiche, nur werden hier die Teilmuster jedesmal neu deklariert. Das ist weniger gut wartbar, wie ich beim "Entwickeln" des Ganzen feststellen musste. Dafür werden keine unnötigen Arrays erzeugt. Außerdem ist der RegEx überraschend einfach konstruiert: Es kommt mit einer Ausnahme ohne Assertions aus. Lediglich das String-Ende wird mit (?:\'|\z) und (?:"|\z) abgefragt. Sonst wird nur einfaches Pattern-Matching verwendet. PHP-Code:
__________________ Wir schreiben schließlich Code und malen keine ASCII-Bilder. Geändert von fireweasel (04.04.2011 um 15:55 Uhr). Grund: ein falsches \x79 durch ein \x9F ersetzt | ||||
| | |
| | ||
| moderatives Dielektrikum Registriert seit: 21.05.2008
Beiträge: 35.987
PHP-Kenntnisse: Fortgeschritten ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() | Zitat:
__________________ -- One pixel is still too big. Please make it smaller. ASAP. Initiative Mittelstand. Die wichtigste Gestaltungsregel im Screendesign ist Pi mal Daumen des Arbeitgebers. -- | |
| | |
| | |
| Erfahrener Benutzer Registriert seit: 14.06.2009
Beiträge: 1.731
PHP-Kenntnisse: Fortgeschritten ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() | Für den Demostring scheint die Lösung zu funktionieren. (War wohl von auszugehen. Wobei ich da mal wieder nicht beurteilen kann, was PCRE intern so treibt. Ich bin schon dazu übergegangen, nur einen einzelnen Aufruf zu testen, da PHP/PCRE einmal kompilierte Patterns cachet, aber – na ja – alles nur gefährliches Halbwissen. Scheint wieder mal die Faustregel zu bestätigen, Operationen – selbst relativ kleine – eher nicht in PHP-Code durchzuführen. Geändert von mermshaus (04.04.2011 um 15:48 Uhr). |
| | |
|
| Themen-Optionen | |
| Thema bewerten | |
|
|
| Besucher kamen über folgende Suchanfragen bei Google auf diese Seite |
| php parameter string, php parameterstring, php string zerlegen leerzeichen anführungszeichen, bash string aufteilen, split string außer bei anführungszeichen, c join split strings escape, bash split quoted string, php parameter = string, mermshaus shell, string separieren shell, bash url zerlegen, php parameterstring to array, string innerhalb anführungszeichen bash, zeichenkette parameter aufspalten, g php escape anführungszeichen, split string quoted escape, php escaping <, php parameter string leerzeichen, javascript anführungszeichen escape, escaping in php |