Klaar voor een nieuwe uitdaging.
Alternatief:
splitsen van een string tot '(' en onthouden welk element de laatste is.
vervolgens ga je verder tot ')' en stop dat bij dat element,
en dan de rest splitsen, waarbij het eerste stukvoor de komma ook weer bij dat element hoort.
Drie deelproblemen. En als je haakjes binnen haakjes hebt, gaat dat automagisch goed.
OK, maar ik ben niet zo'n reguliere expressies held.
[ Voor 70% gewijzigd door Voutloos op 15-01-2004 16:01 ]
{signature}
Klaar voor een nieuwe uitdaging.
1
2
3
4
5
| $string = "Waa, Woe, IF(X, '1', true), Dus"; preg_match_all('/(?:\s*)(([^(,]|\(.*?\))+)(?:,?\s*)/',$string,$array); print_r($array[1]); |
echter als je dit soort dingen hebt:
1
| $string = "Waa, Woe, IF(X, '(blaat)', true), Dus"; |
dan ga je natuurlijk weer de mist in...
Intentionally left blank
Klaar voor een nieuwe uitdaging.
Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'
Intentionally left blank
voorbeeldje (niet getest):
1
2
3
| <?php
$arr = preg_split("/(?<!\([^\)]*),/", $string);
?> |
1
2
3
4
5
6
7
8
| $string = "Waa, Woe, IF(X, '((\\'(1))', true), Dus"; echo $string.'<br /><pre>'; preg_match_all('/(?:\s*)(([^(,\']|\'([^\\\]|\\\\\'?)*?\'|\(([^\']|\'([^\\\]|\\\\\'?)*?\')*?\))+)(?:,?\s*)/',$string,$array); print_r($array[1]); echo '</pre>'; |
Intentionally left blank
Welnee, die stack heb je helemaal niet nodig. Je doet toch niets met karakters die niet binnen de haakjes staan, je hoeft niets te evalueren of wat dan ook. Gewoon een for-lusje met een tellertje voor de haakjes. Als het tellertje 0 is en je komt een komma tegen, de verzamelde string in een array stoppen en anders verder gaan. Even uit de losse pols:crisp:
volgens mij heeft PHP ook geen functie die de 1e occurance uit een verzameling karakters in een string kan vinden, dus ik denk dat je toch karakter voor karakter moet gaan matchen en een soort stack moet gaan bouwen om ( ) en ' ' combo's met daarbinnen komma's uit te filteren.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| $braces = 0; $tmp_str = ''; $array = array (); for ( $i = 0; $i < strlen ( $str ); $i ++ ) { $ch = $str {$i}; if ( $ch == '(' ) { $braces ++; } else if ( $ch == ')' ) { $braces --; } else if ( $ch == ',' && $braces <= 0 ) { // of $braces == 0, maar net hoe 'slim' je de splitter wilt maken $array[]= $tmp_str; $tmp_str = ''; continue; } $tmp_str .= $ch; } if ( strlen ( $tmp_str ) ) { $array []= $tmp_str; } |
Dat is een kwestie van states bijhouden. "ik zit in een string", "ik zit niet in een string", en alleen van de een naar de ander springen als de vorige character geen escape character was (bool)Nog lastiger wordt het als je ook met escape-tekens voor ' gaat werken; ook dat moet je gaan bijhouden.
Da's echt zo lastig allemaal niet, hoor, valt best wel mee. Hell, ik denk dat je zo'n functie sneller geschreven hebt dan een regex ervoor verzonnen hebt
Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz
mwa, die regexp hierboven kostte me 15 minuten geloof ikdrm schreef op 16 januari 2004 @ 13:41:
[...]
Da's echt zo lastig allemaal niet, hoor, valt best wel mee. Hell, ik denk dat je zo'n functie sneller geschreven hebt dan een regex ervoor verzonnen hebt
ik denk alleen dat als ik er morgen weer naar kijk ik weer 15 minuten nodig heb om 'm te snappen, en als er dan nog een bug inzit of het toch anders moet, dan ben ik ws nog langer bezig...
[ Voor 23% gewijzigd door crisp op 16-01-2004 13:59 ]
Intentionally left blank
Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz
Dit moet maar ff voldoen tot nu, later moet ik toch gewoon de zooi als array in de source hebben staan.
Klaar voor een nieuwe uitdaging.
1
2
| strpos( $string, "(" ); strrpos( $string, ")" ); |
aanvulling op de splitter?
Heb toch liever de RegExp.
Confucius said: "In ancient time, learning was for self. Nowadays learning is for others."