preg_match_all соответствует всей строке, если нет пустых строк, и соответствует индивидуально, если есть - PullRequest
1 голос
/ 22 декабря 2010

Эй, Поэтому в php я хочу, чтобы preg_match_all возвращал:

Array ( [0] => text1
[1] => text2
) 

, если ввод:

(text1)

(text2)

и вернуть:

Array ( [0] => 
this is some text
and (bla bla)
 ) 

в случае ввода:

(this is some text
and (bla bla)
)

иначе, если есть новая строка между () и (), они должны совпадать по отдельности, и если нет новых строк, вся строка должна рассматриваться как одна строка

так что в первом примере это работает

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

и во втором примере это работает:

 preg_match_all('/\((.*)\)/s', $match, $matches);

добавив модификатор s но я не могу написать регулярное выражение, которое соответствует двум случаям так, как я хочу

любая помощь высоко ценится

Ответы [ 3 ]

2 голосов
/ 22 декабря 2010

Звучит так, как будто вы хотите разрешить переводы строк внутри скобок, но не две или более строк новой строки подряд.Типичным регулярным выражением для этого может быть

'~\(((?:.|\n(?!\r?\n))*)\)~'

Но это не позволяет использовать различные типы новой строки (например, \r\n или просто \r), и не соответствует, если есть горизонтальные пробелы (например,пробелы или табуляции) в «пустой» строке.Это также не гарантирует, что круглые скобки правильно сбалансированы;Я не знаю, насколько это важно для вас.Попробуйте это регулярное выражение:

'~\(((?:[^\r\n()]|(?:\r\n|[\r\n])(?![ \t]*(?:\r\n|[\r\n]))|(?R))*+)\)~'

Первая альтернатива, [^\r\n()], соответствует чему-либо, что не является новой строкой (или ее частью) или скобками.

Если это не удается, (?:\r\n|[\r\n])пытается сопоставить один из трех видов новой строки, и отрицательный прогноз (?![ \t]*(?:\r\n|[\r\n])) гарантирует, что за новой строкой не следует другая новая строка, либо сразу, либо с пробелами или символами табуляции между ними.

Если третий вариантДостигнуто, следующий символ должен быть либо открытым, в этом случае (?R) пытается применить все регулярное выражение рекурсивно;или близкий друг, в этом случае финал \) завершает матч (или всплывает на следующий более высокий уровень рекурсии).

Конечно, это не учитывает возможность сбежатькруглые скобки, пробелы в Юникоде и разделители строк, или любое другое количество уточнений, но я просто демонстрирую, как применять правило не более одного символа новой строки , и объясняю, почему это труднее сделать, чем ваммог ожидать.

1 голос
/ 22 декабря 2010

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

$arr = preg_split('/(?<=\))\s+(?=\()/',$input);

Посмотреть это

0 голосов
/ 22 декабря 2010

y по умолчанию * и + являются жадными и пытаются использовать максимально длинное совпадение, используя модификатор U, который вы можете использовать, чтобы быть неловким.

preg_match_all('/\((.*)\)/Us', $match, $matches);

должно работать. Вы также можете сделать определенный модификатор несвязным, например так:

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

См. http://php.net/manual/en/regexp.reference.repetition.php и

...