preg_match_all不返回预期值

时间:2014-11-30 09:50:33

标签: php regex

我写了一个相对简单的代码,根据特定的模式从日志文件中提取电子邮件地址;我只对人们向自己发送电子邮件的情况感兴趣。

此日志在日志中显示如下:<%EMAIL%> -> <%SAME-EMAIL%>

  

澄清:

     

&lt;%EMAIL%&gt;代表&#34;&lt;&gt;&#34;内的电子邮件地址字符,后跟&#34; - &GT; &#34;,然后是相同的电子邮件地址。这种模式可能(或可能不会)在一行中多次出现。

for example:

<somename@somesite.com> -> <somename@somesite.com> should match
<somename@somesite.com> -> <othername@othersite.com> should NOT match

我目前使用的代码:

$regx = '/(<[\S]+>)\s->\s\1/';
while ( !feof($myfile) )
{
    $line = fgets($myfile);
    $tmpline = $line;
    if ( preg_match_all($regx, $tmpline, $tmp) )
    {
        $data[$caught++] = $tmp;
    }
}
fclose($myfile);

我的问题是,$tmp数组并不存储实际地址只有&#34; - &GT; &#34;子。 我的输出(print_r($data))如下所示:

Array
(
    [0] => Array
    (
        [0] =>  -> 
    )

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

)
...

我怀疑,问题在于我的正则表达式模式,但不幸的是我还没有能够识别它。

请帮忙。

结束声明:

所有输出都是正确的,但电子邮件在&lt;&gt;内部字符,我的浏览器试图将它们解析为HTML或XML,因此在回显它们时它们不会出现:@

解决方案隐藏在view-source中。

2 个答案:

答案 0 :(得分:1)

这个怎么样?

$data = 
    preg_match_all('/<(\S+)>\s->\s<\1>/', file_get_contents($filename), $m)
    ? $m[1]
    : array()
;
print_r($data);

Demo on ideone.com


使用fgets()的另一个版本。

$data = array();
$fp = fopen($filename, 'r');
while (false !== $row = fgets($fp)) {
    if (preg_match_all('/<(\S+)>\s->\s<\1>/', $row, $m)) {
        foreach ($m[1] as $email) {
            $data[] = $email;
        }
    }
}
if (!feof($fp)) {
    exit('Error');
}
print_r($data);

Demo on ideone.com

答案 1 :(得分:0)

很好,你已经有了解决方案。不确定这是自动任务还是一次性查询。我通常使用notepad ++(或类似的编辑器)来完成这种具有出色的正则表达式替换功能的任务,500k行应该没问题。