考虑这个例子,我尝试获取“原始”电子邮件地址:
<?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";
?>
我认为正则表达式的工作原理如下:
[^ <]*
- 选择不是(^
)空格或尖括号的字符序列<
@
- 选择@
char [^ >,$]*
- 选择不是(^
)空格,尖括号<
,逗号,
或行尾$
的字符序列/m
显然是makes ^
and $
match start/end of lines in addition to start/end of string 大部分都有效,结果是:
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]
?
答案 0 :(得分:2)
只需用\s
替换字符类中的空格即可。因此,这将不包括任何空格字符,包括换行符。
preg_match_all('/([^\s<]*@[^\s>,$]*)/m', $tststr, $matches);
这可以进一步简化如下,即你不需要使用捕获组和多线修饰符m
preg_match_all('/[^\s<]*@[^\s>,$]*/', $tststr, $matches);
char类中的 $
将匹配文字$
符号。不是,它不需要结束。我们不需要在否定的char类中包含\n
,因为\s
完成了这项工作。
preg_match_all('/[^\s<]*@[^\s>,]*/', $tststr, $matches);