用于捕获两个以上新行的正则表达式preg_match_all测试失败

时间:2016-02-22 00:05:03

标签: php regex

我有一个正则表达式 - / \ r \ n | \ r | \ n {3,} / g - 在Javascript中工作以捕获用户连续输入3个以上换行符的实例。然后我接受该实例并将其转换回2个换行符。

现在,我正在尝试在PHP中进行服务器端验证,并且在没有能够使用'' flag,我收集我需要使用preg_match_all()。但是,如果没有实例,我似乎无法获得preg_match_all(" / \ r \ n | \ r | \ n {3,} /",$ value)返回0连续三次换行 - 由于某种原因,似乎忽略了正则表达式的{3,}部分。

我通过文本区域输入传入验证的测试文本($ value)是:

Test

Test

最多,它连续有两个新行,所以它应该返回0个匹配 - 这正确反映在客户端的Javascript结果中。我尝试过的preg_match_all的排列是:

preg_match_all( "/\r\n|\r|\n{3,}/", $value); -> 2 matches
preg_match_all( "/(\r\n|\r|\n{3,})/", $value); -> 2 matches
preg_match_all( "/(\r\n|\r|\n){3,}/", $value); -> 1 match
preg_match_all( "/[(\r\n|\r|\n)]{3,}/", $value); -> 1 match
preg_match_all( "/([(\r\n|\r|\n)]{3,})/", $value); -> 1 match
preg_match_all( "/(\r\n|\r|\n{3,})+/", $value); -> 1 match

我的原始正则表达式 - / \ r \ n | \ r | \ n {3,} / g - 适用于http://www.regexr.com/上的测试(即上述测试文本没有匹配)。当我运行它时,它也可以工作:

preg_match_all( "/\r\n|\r|\n{3,}/", "Test\n\nTest"); -> 0 matches
preg_match_all( "/\r\n|\r|\n{3,}/", "Test\n\n\nTest"); -> 1 match
preg_match_all( "/\r\n|\r|\n{3,}/", "Test\n\n\nTest\n\nTest\n\n\nTest"); -> 2 matches

我不确定表单提交如何影响preg_match_all测试的结果。这可能是我非常简单的事情 - 如果有人能指出我正确的方向,那将非常感激!谢谢。

3 个答案:

答案 0 :(得分:2)

为了将' \ r``作为独立的换行符匹配,您需要制作
它是一个原子组,因此引擎不会尝试匹配无效的部分。

这似乎有效 -

(?>\r?\n|\r){3,}

对于您的测试用例

Test

Test 

它找不到3个有效的换行符。

答案 1 :(得分:1)

由于您正在搜索换行符,因此您必须搜索/ r(Mac),/ n(Unix)或/ r / n(Windows) - 并且只搜索其中一次或更多次 - 而不是混合使用那些。

所以模式应该是:

/(\r\n){3,}|(\n{3,})|(\r{3,})/

还有一些测试代码:

$pattern = "/(\r\n){3,}|(\n{3,})|(\r{3,})/";
$a = preg_match_all( "{$pattern}", "Test\r\n\r\n\r\nTest");
assert($a===1);

$a = preg_match_all( "{$pattern}", "Test\n\n\nTest");
assert($a===1);

$a = preg_match_all( "{$pattern}", "Test\r\r\rTest");
assert($a===1);

$a = preg_match_all( "{$pattern}", "Test\r\n\r\nTest");
assert($a===0);

答案 2 :(得分:1)

尝试使用此preg_match_all("/\r?\n|\r){3,}/", $value); 这意味着\r\n\n或\ r(括号内)应出现三次或更多次。

您的大多数人尝试匹配\r\n\r或树时\n