preg_split Problem
lima-city → Forum → Programmiersprachen → PHP, MySQL & .htaccess
apache
ausdruck
ausdrcken
beitrag
connection
date
ergebnis
ersatz
extension
folgendes ergebnis
gewnschtes ergebnis
inside
keep
kurz fassung
scout
support
tag
verzicht
zeichenkette
zweck
-
Ich verwende folgenden regulären tag/ausdruck">ausdruck mit preg_split mit den flags REG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_OFFSET_CAPTURE
$regex = "~\{(literal)\}(.*?)\{(/literal)\}|\{(.*?)\}~s";
das ganze sollte mir also beim durchsuchen des Strings "df{g}sd" folgendes zurückgeben:
Array(
[0] => Array
(
[0] => df
[1] => 0
)
[1] => Array
(
[0] => g
[1] => 3
)
[2] => Array
(
[0] => sd
[1] => 5
)
)
jedoch bekomme ich folgende rückgabe:
Array(
[0] => Array
(
[0] => df
[1] => 0
)
[1] => Array
(
[0] =>
[1] => -1
)
[2] => Array
(
[0] =>
[1] => -1
)
[3] => Array
(
[0] =>
[1] => -1
)
[4] => Array
(
[0] => g
[1] => 3
)
[5] => Array
(
[0] => sd
[1] => 5
)
)
Hier noch mal der original 'code' (nur testcode deshalb so durcheinander *hüstel*)
echo '<pre>'.print_r(preg_split( "~\{(literal)\}(.*?)\{(/literal)\}|\{(.*?)\}~s", "df{g}sd", -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_OFFSET_CAPTURE ),1).'</pre>';
Ich habe übrigens die beiden branches("\{(literal)\}(.*?)\{(/literal)\}" und "\{(.*?)\}") seperat getestet die funktionieren wie sie sollen, auch wenn ich z.B. "df{g}s{literal}asd{as}d{/literal}" als subject reingebe kommt im großen und ganzen das gewünschte ergebniss raus, "asd{as}d" wird nicht weiter aufgeteilt, jedoch habe ich bei im ErgebnissArray wieder unter den keys 1-3 einen leeren string mit dem offset -1.
Allein schon das negative offset macht mich stutzig. Liegt es an mir oder liegt es an php
//edit:
Beim rumprobieren ist ir noch folgendes aufgefallen, wenn ich die branches vertausche, also "~\{(.*?)\}|\{(literal)\}(.*?)\{(/literal)\}~s" als regex nehme dnan bekomme ich nicht die drei treffer miti dem offset -1, allerdings erreiche ich dann mein ziel nicht mehr weil die literal tags im ersten teil verarbeitet werden.
Beitrag geaendert: 24.5.2007 22:58:06 von coderinside
Beitrag geaendert: 25.5.2007 0:30:00 von coderinside -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage
-
Sorry, aber was zum Geier sind Literal-Tags ?
Habe das mal kurz durchgetestet und bei mir kommt folgendes raus...
<? echo "<pre>" .print_r( preg_split( '~\{(.*?)\}|\{(literal)\}(.*?)\{(/literal)\}~s', 'df{g}sd', -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_OFFSET_CAPTURE ) ,true) ."</pre>"; ?>
bringt folgendes Ergebnis:
Array ( [0] => Array ( [0] => df [1] => 0 ) [1] => Array ( [0] => g [1] => 3 ) [2] => Array ( [0] => sd [1] => 5 ) )
Hat es evtl. was mit dem true bzw. 1 beim print_r zu tun? ...bei mir ging es nämlich mit der 1 nicht ;-(
Grüßle
Beitrag geaendert: 25.5.2007 13:53:25 von scout -
"df{g}s{literal}asd{as}d{/literal}"
Ok nimmm das als Ersatz subject und schau bitte mal ob du auch keine
[X] => Array ( [0] => [1] => -1 )
treffer bekommst.
Des weiteren würde mich interessieren womit du arbeitest (PHP Version, OS, CGIPHP oder PHP als modul, pcre version), da mir halt die oben beschriebenen treffer wie ein bug vorkommen.
Zu den "Literal Tags": es gibt eine Templateengine namens Smarty (smaty.php.net) und diese verarbeitet u.a. {if}{else} etc. in templates, allerdings hat die engine trotz optimierung doch etwasoverload (wie das nun mall so ist bei eierlegenden wollmilchsäuen die fast alles können) und ich wollte für meine Zwecke eine vereinfachte version (so ca 50 statt 1000 zeilen) allerdings wollte ich nicht auf die s.g.literal tags verzichten, das ist quasi eine NoParse anweisung die bewirkt das alles dazwischen einfach so wiedergegeben wird wie es da steht ohne interpretiert zu werden.
In der Kurz Fassung: Wenn es literal tags bei Php geben würde dann würde alles dazwischen einfach per echo ausgegeben werden und nicht interpretiert werden (e.g.) <?php {literal}echo 'dies';{/literal} echo 'dies'; ?>
würde dann theoretisch "echo 'dies';dies" ausgeben
Es ist in etwa wie \Q...\E in Pcre
PCRE does support the \Q...\E escape for quoting substrings. Charac-
ters in between are treated as literals.
Beitrag geaendert: 25.5.2007 14:47:46 von coderinside -
Also bei (preg_split ( string Suchmuster, string Zeichenkette ,...) :
Suchmuster: '~\{(.*?)\}|\{(literal)\}(.*?)\{(/literal)\}~s'
Zeichenkette: 'df{g}s{literal}asd{as}d{/literal}'
bekomme ich:
Array
(
[0] => Array
(
[0] => df
[1] => 0
)
[1] => Array
(
[0] => g
[1] => 3
)
[2] => Array
(
[0] => s
[1] => 5
)
[3] => Array
(
[0] => literal
[1] => 7
)
[4] => Array
(
[0] => asd
[1] => 15
)
[5] => Array
(
[0] => as
[1] => 19
)
[6] => Array
(
[0] => d
[1] => 22
)
[7] => Array
(
[0] => /literal
[1] => 24
)
[8] => Array
(
[0] =>
[1] => 33
)
)
Ist wahrscheinlich nicht dein gewünschtes Ergebnis...
...nehme an es soll herauskommen:
Array
(
[0] => Array
(
[0] => df
[1] => 0
)
[1] => Array
(
[0] => g
[1] => 3
)
[2] => Array
(
[0] => s
[1] => 5
)
[3] => Array
(
[0] => asd{as}d
[1] => 15
)
)
oder?
...sorry muß leider weg, werde mir das später nochmal ansehen
Grüßle
PS:
Ist der xampp 1.5.5 von Apachefriends.org...
System Windows NT TOWER 5.1 build 2600
Build Date Feb 7 2007 23:10:31
Configure Command cscript /nologo configure.js "--enable-snapshot-build" "--with-gd=shared"
Server API Apache 2.0 Handler
Virtual Directory Support enabled
Configuration File (php.ini) Path C:\xampp\apache\bin\php.ini
PHP API 20041225
PHP Extension 20060613
Zend Extension 220060519
Debug Build no
Thread Safety enabled
Zend Memory Manager enabled
IPv6 Support enabled
Registered PHP Streams php, file, data, http, ftp, compress.zlib, https, ftps, zip
Registered Stream Socket Transports tcp, udp, ssl, sslv3, sslv2, tls
Registered Stream Filters convert.iconv.*, string.rot13, string.toupper, string.tolower, string.strip_tags, convert.*, consumed, zlib.*
apache2handler
Apache Version Apache/2.2.4 (Win32) DAV/2 mod_ssl/2.2.4 OpenSSL/0.9.8e mod_autoindex_color PHP/5.2.1
Apache API Version 20051115
Server Administrator admin@localhost
Hostname:Port localhost:80
Max Requests Per Child: 0 - Keep Alive: on - Max Per Connection: 100
Timeouts Connection: 300 - Keep-Alive: 5
Virtual Server No
Server Root C:/xampp/apache
Loaded Modules core mod_win32 mpm_winnt http_core mod_so mod_actions mod_alias mod_asis mod_auth_basic mod_authn_default mod_authn_file mod_authz_default mod_authz_groupfile mod_authz_host mod_authz_user mod_cgi mod_dav mod_dav_fs mod_dir mod_env mod_include mod_info mod_isapi util_ldap mod_log_config mod_mime mod_negotiation mod_setenvif mod_status mod_ssl mod_autoindex_color mod_php5
Beitrag geaendert: 25.5.2007 16:25:47 von scout -
Jo das 2 soll rauskommen, man beachte den unterschied unserer regulären ausdrücke
Deiner: ~\{(.*?)\}|\{(literal)\}(.*?)\{(/literal)\}~s
Meiner: ~\{(literal)\}(.*?)\{(/literal)\}|\{(.*?)\}~s
Meiner bringt auch fast das von dir gelistete ergebniss nur sind da halt noch die treffer mit dem offset -1 die nicht siein sollen.
Warum deiner nicht so funzt wie eer soll ist einfach, er braucht die alternative mit dem literal nicht auszuprobieren weil er schon vorher einen treffer findet
(eg "~camel|came|camera~i" findet in "camera" auch nur "came"
da "camel" => mismatch try next
"came" => match, return, deshalb müsste man ihn erst "camera" und dann "came" testen lassen.
Mfg coder- inside
versuch doch bitte mal
$res = preg_split( "~\{\*(literal)\}(.*?)\{(/literal)\}|\{(.*?)\}~s", "df{g}s{literal}asd{as}d{/literal}", -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_OFFSET_CAPTURE ); echo '<pre>'.print_r($res, 1).'</pre>';
denn da bekomme ich:
Array
(
[0] => Array
(
[0] => df
[1] => 0
)
[1] => Array
(
[0] =>
[1] => -1
)
[2] => Array
(
[0] =>
[1] => -1
)
[3] => Array
(
[0] =>
[1] => -1
)
[4] => Array
(
[0] => g
[1] => 3
)
[5] => Array
(
[0] => s
[1] => 5
)
[6] => Array
(
[0] =>
[1] => -1
)
[7] => Array
(
[0] =>
[1] => -1
)
[8] => Array
(
[0] =>
[1] => -1
)
[9] => Array
(
[0] => literal
[1] => 7
)
[10] => Array
(
[0] => asd
[1] => 15
)
[11] => Array
(
[0] =>
[1] => -1
)
[12] => Array
(
[0] =>
[1] => -1
)
[13] => Array
(
[0] =>
[1] => -1
)
[14] => Array
(
[0] => as
[1] => 19
)
[15] => Array
(
[0] => d
[1] => 22
)
[16] => Array
(
[0] =>
[1] => -1
)
[17] => Array
(
[0] =>
[1] => -1
)
[18] => Array
(
[0] =>
[1] => -1
)
[19] => Array
(
[0] => /literal
[1] => 24
)
[20] => Array
(
[0] =>
[1] => 33
)
)
ich hoffe das es bei dir besser klappt
Beitrag geaendert: 25.5.2007 16:46:54 von coderinside -
Also mit dem Reg: '~\{\*(literal)\}(.*?)\{(/literal)\}|\{(.*?)\}~s' auf den String: 'df{g}s{literal}asd{as}d{/literal}' angewandt, erhalte ich auch dein Ergebnis.
Doch nochmal zu deinem Problem... wenn ich es richtig verstanden habe möchtest du einen Reg-Ausdruck haben der bei dem
String 'df{g}s{literal}asd{as}d{/literal}'
folgendes Ergebnis bringt:
Array
(
[0] => Array
(
[0] => df
[1] => 0
)
[4] => Array
(
[0] => g
[1] => 3
)
[5] => Array
(
[0] => s
[1] => 5
)
[6] => Array
(
[0] => asd{as}d
[1] => 15
)
)
Möchtest du das raus bekommen? Oder mit den Arrays für die Literale?
Grüßle -
Also mit dem RegEx:
<? echo '<pre>' .print_r( preg_split( '~\{literal\}(.*?)\{/literal\}|\{(.*?)\}~s', 'df{g}s{literal}asd{as}d{/literal}', -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_OFFSET_CAPTURE | PREG_SPLIT_NO_EMPTY ) ,true) .'</pre>'; ?>
werden alle Ausdrücke an den {} geteilt, außer wenn diese von literal eingeschlossen sind.
Bei String: 'df{g}s{literal}asd{as}d{/literal}'
käme also folgendes Ergebnis:
Array
(
[0] => Array
(
[0] => df
[1] => 0
)
[1] => Array
(
[0] => g
[1] => 3
)
[2] => Array
(
[0] => s
[1] => 5
)
[3] => Array
(
[0] => asd{as}d
[1] => 15
)
)
Falls es nicht das richtige ist, einfach nochmal Aufgabenstellung spezifizieren. danke.
Soll zum Bsp. auch 'df{g}s{literal}a{bc}d{literal}e{f}g{/literal}h{/literal}' verarbeitet werden? Wenn ja, wie soll das Ergebnis aussehen?
Grüßle
Beitrag geaendert: 26.5.2007 20:09:12 von scout -
Also aufgabenstellung wurde korrekt verstanden, und naja "df{g}s{literal}a{bc}d{literal}e{f}g{/literal}h{/literal}" müsste schon so verarbeitet werden, das nur folgender teil nach dme ersten literal herausgesaugt wird:
a{bc}d{literal}e{f}g
desweiteren hatte es einen grund das PREG_SPLIT_NO_EMPTY nicht gesetzt ist:
theoretisch weis man damit immer ob es sich um einen tag oder text handelt denn nomalerweise sollte folgendes "{taga}{tagb}"
dann wie folgt aufgeteilt sein
array("","taga","","tagb","");
(wann immer arrayindex%2 = true (ungerade) haben wir einen tag falls false normalen text) -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage