2010-10-03 34 views
0

J'ai essayé de chercher la réponse à cette question, mais je n'ai rien trouvé d'utile dans cette situation. Il est possible que je ne cherche pas les termes corrects.Regex - ignorer certains caractères entre guillemets

J'ai des problèmes avec cette regex. Considérez cette chaîne:

$str = "(1, 2, 'test (foo) bar'), (3, 4, '(hello,world)')"; 

Je veux finir avec un tableau multidimensionnel, comme ceci:

$arr = array(
    array(1, 2, 'test (foo) bar'), 
    array(3, 4, '(hello,world)') 
); 

Je me dis que je pouvais courir un regex à scinder en différentes chaînes comme « (1, 2 , 'test (foo) bar') "et" (3, 4, '(bonjour, monde)') ", puis exécutez une regex sur chacun de ceux à diviser par une virgule, mais comme vous pouvez le voir, mon problème est le les données ont des parenthèses et des virgules dans diverses chaînes, et j'aimerais les ignorer.

Jusqu'à présent, j'ai ceci, qui fait la première partie comme je le voulais, sauf s'il y a des parenthèses dans les données, alors ça casse.

preg_match_all('/\((.*?)\),?/', $str, $matches); 

Il me donne ceci:

Array 
(
    [0] => Array 
     (
      [0] => (1, 2, 'test (foo) 
      [1] => (3, 4, '(hello,world) 
     ) 

    [1] => Array 
     (
      [0] => 1, 2, 'test (foo 
      [1] => 3, 4, '(hello,world 
     ) 

) 

Il tronque les données, naturellement. Que puis-je faire pour ignorer les parenthèses qui sont entre guillemets? Si je peux les ignorer, alors à l'étape suivante lorsque je diviserai chacun de ces matchs, je serai en mesure d'ignorer les virgules.

Merci!

Répondre

0

En général, vous ne pouvez pas faire cela avec des regex. Mais dans ce cas, vous pouvez essayer cette expression:

\(([^']*?'.*?')\),? 
+0

cela fonctionne lorsque les données a des cordes, mais il échoue sur les chaînes comme: –

+0

(1, 1), (5, 0), (10, 0), (14, 1), (15, 0), (20, 1), (25, 0), (29, 1), (39, 0) –

+0

Essayez celui-ci \\ (([^ '] *?'. *? ') \\) | \\ (([^'] *?) \\) ,? – Max

0

([0-9]+), (\'([A-Za-z0-9(), ]+)\')?

Cela semble faire ce que vous voulez.

$matches Array: 
(
[0] => Array 
    (
     [0] => 1, 
     [1] => 2, 'test (foo) bar' 
     [2] => 3, 
     [3] => 4, '(hello,world)' 
    ) 

[1] => Array 
    (
     [0] => 1 
     [1] => 2 
     [2] => 3 
     [3] => 4 
    ) 

[2] => Array 
    (
     [0] => 
     [1] => 'test (foo) bar' 
     [2] => 
     [3] => '(hello,world)' 
    ) 

[3] => Array 
    (
     [0] => 
     [1] => test (foo) bar 
     [2] => 
     [3] => (hello,world) 
    ) 
) 

Est-ce plus proche?

+0

oh! vous avez besoin du 1, 2 et 3, 4 aussi. Pardon. un moment. – beta0x64

+0

[A-Za-z0-9(),] est préférable d'écrire comme [^ '] – Max

+0

bien, je vais aussi avoir des caractères non-alphanumériques, donc je ne peux pas utiliser les plages. –

0

Essayez ce modèle:

$pattern = '/((?:.*?),(?:.*?),(?:.*?)),(.*)/'; 

ce qui a la sortie

Array 
(
    [0] => Array 
     (
      [0] => (1, 2, 'test (foo) bar'), (3, 4, '(hello,world)') 
     ) 

    [1] => Array 
     (
      [0] => (1, 2, 'test (foo) bar') 
     ) 

    [2] => Array 
     (
      [0] => (3, 4, '(hello,world)') 
     ) 

)