Regex - игнорировать определенные символы в кавычках

Я пытался найти ответ на этот вопрос, но не нашел ничего полезного в этой ситуации. Возможно, я не ищу правильные термины.

У меня проблемы с этим регулярным выражением. Рассмотрим эту строку:

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

Я хочу получить многомерный массив, например:

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

Я полагаю, что могу запустить регулярное выражение, чтобы разделить его на отдельные строки, такие как "(1, 2, 'test (foo) bar')" и "(3, 4, '(hello,world)')", а затем запустить регулярное выражение для каждого из них для разделения запятой, но, как вы можете видеть, моя проблема заключается в том, что данные имеют круглые скобки и запятые в разных строках, и я бы хотел их игнорировать.

Пока у меня есть это, которое делает первую часть так, как я хотел, за исключением того, что если в данных есть скобки, то оно ломается.

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

Это дает мне это:

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
        )

)

Это усекает данные, естественно. Что я могу сделать, чтобы игнорировать скобки в кавычках? Если я смогу их игнорировать, то на следующем шаге, когда я разделю каждое из этих совпадений, я смогу игнорировать запятые.

Спасибо!


person Adam Jackett    schedule 03.10.2010    source источник


Ответы (3)


В общем, вы не можете сделать это с регулярными выражениями. Но в этом случае вы можете попробовать это выражение:

\(([^']*?'.*?')\),?
person Max    schedule 03.10.2010
comment
это работает, когда данные имеют строки, но не работают с такими строками, как: - person Adam Jackett; 04.10.2010
comment
Попробуйте этот \(([^']*?'.*?')\)|\(([^']*?)\),? - person Max; 04.10.2010
comment
Это намного ближе, но в некоторых случаях это вызывает у меня проблему - я сначала пытаюсь выяснить, что вызывает это. Спасибо. - person Adam Jackett; 04.10.2010
comment
Есть ли у вас «вложенные» строки, например «бла-бла-бла-бла»? - person Max; 04.10.2010
comment
Это может быть все. Я собираю пример того, что вызывает проблемы. - person Adam Jackett; 04.10.2010
comment
$str = (4, 'Купоны', '', 3, 3), (5, 'Программа лояльности клиентов', 'это (есть) не работает', 3, 1); просто дает мне это: Массив ( [0] => Массив ( [0] => (есть) ) [1] => Массив ( [0] => ) [2] => Массив ( [0] => есть ) ) - person Adam Jackett; 04.10.2010
comment
Тогда я думаю, что это невозможно сделать только с помощью регулярных выражений. - person Max; 04.10.2010
comment
Оу... это очень плохо. Это было так близко. В любом случае спасибо. - person Adam Jackett; 04.10.2010

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

Кажется, это делает то, что вы хотите.

$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)
    )
)

Это ближе?

person 0x1F602    schedule 03.10.2010
comment
ой! вам нужны 1, 2 и 3, 4 тоже. Прости. один момент. - person 0x1F602; 04.10.2010
comment
[A-Za-z0-9(), ] лучше писать как [^'] - person Max; 04.10.2010
comment
ну, у меня также будут не буквенно-цифровые символы, поэтому я не могу использовать диапазоны. - person Adam Jackett; 04.10.2010
comment
Это слишком сильно разделяет вещи. Не то, что я ищу. Спасибо хоть. - person Adam Jackett; 04.10.2010

Попробуйте этот шаблон:

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

это имеет выход

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)')
        )

)
person firecast    schedule 07.08.2013