preg_match_all匹配整个字符串,如果没有空行,则单独匹配(如果有)

时间:2010-12-21 23:05:10

标签: php regex pcre

嘿 所以在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 个答案:

答案 0 :(得分:2)

听起来你想在括号内允许换行符,但不能连续两行或多行换行符。典型的正则表达式可能是

'~\(((?:.|\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]))会确保换行符不会立即或使用空格或其他换行符他们之间的标签。

如果达到第三个选项,则下一个字符应该是open-paren,在这种情况下(?R)尝试递归地应用整个正则表达式;或者近距离,在这种情况下,最终\)完成比赛(或弹出到下一个更高级别的递归)。

当然,这并没有考虑转义括号,Unicode空格和行分隔符或任何其他改进的可能性,但我真的只是在演示如何强制执行不超过一个换行符规则,并解释为什么它比你想象的更难做。

答案 1 :(得分:1)

尝试使用preg_split分隔空格上的输入字符串,如果前面有),后面有(

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

See it

答案 2 :(得分:0)

默认*和+是贪婪的,并尝试使用U修饰符来使用最长的匹配,你可以使用pcre是不合适的。

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

应该有效。你也可以这样做一个特定的修饰符:

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

请参阅http://php.net/manual/en/regexp.reference.repetition.php