让preg_match_all在换行符处停止捕获?

时间:2015-07-05 10:03:06

标签: php regex

考虑这个例子,我尝试获取“原始”电子邮件地址:

<?php
$tststr = 'To: user1@example1.com
To: user2@example2.com, anotheruser3@example3.com
To: User <user4@example4.com>
To: User <user5@example5.com>, Another User <anotheruser6@example6.com>
';

//~ preg_match('/([^ <]*@[^ >,]*)/', $tststr, $matches); // no /g
preg_match_all('/([^ <]*@[^ >,$]*)/m', $tststr, $matches);

foreach ($matches as $key=>$val) {
  //~ print("val [".$key."] = ". $val . "\n");
  foreach ($val as $key1=>$val1) {
    print("val [".$key."][".$key1."] = ". $val1 . "\n");
  }
}

print "'".$matches[0][0]."'\n";
?>

我认为正则表达式的工作原理如下:

大部分都有效,结果是:

val [0][0] = user1@example1.com
To:
val [0][1] = user2@example2.com
val [0][2] = anotheruser3@example3.com
To:
val [0][3] = user4@example4.com
val [0][4] = user5@example5.com
val [0][5] = anotheruser6@example6.com
val [1][0] = user1@example1.com
To:
val [1][1] = user2@example2.com
val [1][2] = anotheruser3@example3.com
To:
val [1][3] = user4@example4.com
val [1][4] = user5@example5.com
val [1][5] = anotheruser6@example6.com
'user1@example1.com
To:'

...除了,正如你所看到的,匹配[0] [0]实际上包含换行符,下一行是“To:”!

那么,我怎样才能在行尾有preg_match_all停止捕获?

子问题:为什么我必须在$matches[0]$matches[1]中使用相同的结果集?我可以忽略$matches[1],只是处理$matches[0]

1 个答案:

答案 0 :(得分:2)

只需用\s替换字符类中的空格即可。因此,这将不包括任何空格字符,包括换行符。

preg_match_all('/([^\s<]*@[^\s>,$]*)/m', $tststr, $matches);

这可以进一步简化如下,即你不需要使用捕获组和多线修饰符m

preg_match_all('/[^\s<]*@[^\s>,$]*/', $tststr, $matches);

DEMO

char类中的

$将匹配文字$符号。不是,它不需要结束。我们不需要在否定的char类中包含\n,因为\s完成了这项工作。

preg_match_all('/[^\s<]*@[^\s>,]*/', $tststr, $matches);