Regexp gesucht
Alex
- php
Hallo,
leider bin ich in Sachen Regexp nicht sonderlich fit.
Ich suche eine Regex die mir Strings nach dem folgenden Muster außereinander nimmt.
string/int_string/int_"/'string/int"/'
Also das heißt ich habe beliebig viele Zeichenketten zwischen beliebig vielen Leerzeichen wenn aber ein String in " oder ' steht soll er auch wenn leerzeichen dazugehören als einer erkannt werden, diesem String sollten dann " oder ' maskierbar sein also '
Beispiel
copy abc de fghi "Test Test "Test" Test 'Test' Test" 'Test'
Sollte dann folgendes geben:
Array (
0 => copy
1 => abc
2 => de
3 => fghi
4 => Test Test "Test" Test 'Test' Test
5 => Test
)
Kann mir da jemand helfen ;-) ?
Hallo,
leider bin ich in Sachen Regexp nicht sonderlich fit.
Ich suche eine Regex die mir Strings nach dem folgenden Muster außereinander nimmt.string/int_string/int_"/'string/int"/'
Also das heißt ich habe beliebig viele Zeichenketten zwischen beliebig vielen Leerzeichen wenn aber ein String in " oder ' steht soll er auch wenn leerzeichen dazugehören als einer erkannt werden, diesem String sollten dann " oder ' maskierbar sein also '
Beispiel
copy abc de fghi "Test Test "Test" Test 'Test' Test" 'Test'
Sollte dann folgendes geben:
Array (
0 => copy
1 => abc
2 => de
3 => fghi
4 => Test Test "Test" Test 'Test' Test
5 => Test
)Kann mir da jemand helfen ;-) ?
Ok das ist kein leichtgewichtiger Keks.
Ich komme von perl her, und versuche mal einen Ansatz.
/"([^"]+)"/ findet leider \
ergo darf man " nur dann matchen, wenn es kein \ vorangeht
Da wir es mit Tokens zu tun haben
Token "Token Pair" Token
kann ich schon mal die Bdingung knüpfen, dass dem einleitenden " ein Whitespace oder der Starpunkt des Suchstrings vorangehen muss.
/(?:^|\s+)"(.+)"/
Das matcht nun aber immer noch.
Ich kann noch die Bedingung anknüpfen, dass dem End " kein \ vorangehen darf
/(?:^|\s+)"(.*?[^\"])"/
die Gleiche Version mit '
/(?:^|\s+)'(.*?[^\'])'/
Und natürlich sollen Tokens gefunden werden, die für die gilt:
[^\s"']+
/(?:^|\s+)([^\s"'][^\s]*)/
Jetzt setzen wir das zusammen
/(?:^|\s+)([^\s"'][^\s]*)|(?:^|\s+)"(.*?[^\"])"|(?:^|\s+)'(.*?[^\'])'/
Aufpassen muss man hier, dass das gewünschte Resultat entweder in $1, $2 oder $3 drin ist
Wir konnen noch etwas ausfaktorieren:
/(?:^|\s+)
(?:
([^\s"'][^\s]*)
|
"(.*?[^\"])"
|
'(.*?[^\'])'
)
(?:\s+|$)
/x
Und hier das finale perlscript
#!C:/Programme/Perl/bin/perl.exe -w
#
use strict;
BEGIN {
use CGI::Carp qw(carpout);
open(LOG, ">>error.txt") or die "Unable to append to error.txt: $!\n";
carpout(*LOG);
}
my $s=q(a bc def "ghi jkl \"m\" n \'o\' p" 'q');
while( $s =~ s/
(?:^|\s+)
(?:
([^\s"'][^\s]*)
|
"(.*[^\\"])"
|
'(.*[^\\'])'
)
(?:\s+|$)
//x){
print $1.$2.$3, "\n";
}
sleep(10);
exit;
__END__
Sollte weiter getestet werden.
Nach PHP umschreiben bleibt eine Übung für den Fragesteller.
mfg Beat
Danke erstmal,
leider funktioniert das bei mir nicht wirklich.
Ich habe mir jetzt so geholfen:
$input_data = Von Quelle lesen
$quotations_array = array (0 => '"', 1 => "'");
$input_data .= ' ';
$quotation == false;
// Zeichenkette durchlaufen
for($i=0;$i<strlen($input_data);$i++) {
if(in_array($input_data[$i], $quotations_array)) {
if (@substr($buffer,(strlen($buffer)-1),1) != '\\') {
if($quotation == false) {
$quotation = true;
$quotation_input_data = $input_data[$i];
} else {
if ($input_data[$i] == $quotation_input_data) {
$quotation = false;
}
}
}
}
if($input_data[$i] != ' ') {
$buffer.= $input_data[$i];
}
else {
if ($quotation == true) {
$buffer.= $input_data[$i];
} else {
if ($buffer != '') $buffer_array[] = trim($buffer);
$buffer = '';
}
}
}
if (!empty ($buffer)) $buffer_array[] = trim($buffer);
Was sogar zu funktionieren scheint ;-) Ich bin mir allerdings nicht ganz sicher ob es wirklich immer tut.
Mir wurde es zwischendrin etwas zu viel ;-)