PHP中的这个正则表达式是否真的有效?

时间:2009-03-21 11:53:43

标签: php regex

我希望正则表达专家可以告诉我为什么会出错:

这个正则表达式:

$pattern = '/(?<percent>[0-9]{1,3}\.[0-9]{1,2})% of (?<filesize>.+) at/';

应匹配此类字符串:

[download] 87.1% of 4.40M at 107.90k/s ETA 00:05 
[download] 89.0% of 4.40M at 107.88k/s ETA 00:04 
[download] 91.4% of 4.40M at 106.09k/s ETA 00:03 
[download] 92.9% of 4.40M at 105.55k/s ETA 00:03

正确?是否有任何可能出现错误的正则表达式无法与上述输入相匹配?完全用法:

while(!feof($handle))
{
    $progress = fread($handle, 8192);
    $pattern = '/(?<percent>[0-9]{1,3}\.[0-9]{1,2})% of (?<filesize>.+) at/';
    if(preg_match_all($pattern, $progress, $matches)){
    //matched
    }
}

fread 正在读取多少正在影响正则表达式才能正常工作?

我确实需要确认,因为我正在尝试确定它为什么不能在新服务器上运行。此问题与Change in Server Permits script not to work. Can this be due to PHP.ini being different?

有关

全部谢谢

更新2

我已经制作了一个测试脚本来测试正则表达式,但即使它本身也不起作用?

<?php 

error_reporting(E_ALL);

echo 'Start';

$progress = "[download]75.1% of 4.40M at 115.10k/s ETA 00:09 [download] 77.2% of 4.40M at 112.36k/s ETA 00:09 [download] 78.6% of 4.40M at 111.41k/s ETA 00:08 [download] 80.3% of 4.40M at 110.80k/s ETA 00:07 [download] 82.3% of 4.40M at 110.30k/s ETA 00:07 [download] 84.3% of 4.40M at 108.33k/s ETA 00:06 [download] 85.7% of 4.40M at 107.62k/s ETA 00:05 [download] 87.5% of 4.40M at 107.21k/s ETA 00:05 [download] 89.5% of 4.40M at 105.10k/s ETA 00:04 [download] 90.7% of 4.40M at 106.45k/s ETA 00:03 [download] 93.2% of 4.40M at 104.92k/s ETA 00:02 [download] 94.8% of 4.40M at 104.40k/s ETA 00:02 [download] 96.5% of 4.40M at 102.47k/s ETA 00:01 [download] 97.7% of 4.40M at 103.48k/s ETA 00:01 [download] 100.0% of 4.40M at 103.15k/s ETA 00:00 [download] 100.0% of 4.40M at 103.16k/s ETA 00:00
";

$pattern = '/(?<percent>\d{1,3}\.\d{1,2})%\s+of\s+(?<filesize>[\d.]+[kBM]) at/';

if(preg_match_all($pattern, $progress, $matches)){
    echo 'match';
}

echo '<br>Done<br>';    

?>

5 个答案:

答案 0 :(得分:5)

我对命名捕获并不熟悉,但我认为在PHP中它应该是:

$pattern = '/(?P<percent>[0-9]{1,3}\.[0-9]{1,2})% of (?P<filesize>.+) at/';

注意问号后的 P

<强>来源:

答案 1 :(得分:1)

正则表达式对我来说似乎没问题。

但是,我会改进一些事情:

  • "\s+"的空格,而不是" "
  • 数字"\d",而不是"[0-9]"(同样的事情,它只是更短)
  • 文件大小不是".+",而是更具体的

这将是我的版本:

(?<percent>\d{1,3}\.\d{1,2})%\s+of\s+(?<filesize>[\d.]+[kBM])

根据您对错误数字格式的预期(我猜:不太可能),您可以将其缩短为:

(?<percent>[\d.]+)%\s+of\s+(?<filesize>[\d.]+[kBM])

答案 2 :(得分:1)

如果您的流实际上在一次读取中提供了超过8kb的数据,您可能会截断最后一行,这将阻止它匹配。尝试使用fgets()一次一行地读取流。

答案 3 :(得分:1)

我会使用fgets()来读取基于行的,因为你想要匹配每行我假设。如果您改为匹配每行,则不需要使用preg_match_all,而只需要使用preg_match。

您的百分比似乎只有1位小数,但您匹配1,2位数?

答案 4 :(得分:0)

  

这个正则表达式有什么问题可以解决它不能与上面的输入相匹配吗?

不是我能看到的,但有一些东西确实出错使得它太匹配了:如果你真的没有新行,那么这个:

(?P<filesize>.+) at

可以从输入中的开头到最后一个“at”贪婪地匹配。因此,如果我匹配您发布的整个示例输入,我得到&lt; percent&gt;的:

75.1

(好)和文件大小:

4.40M at 115.10k/s ETA 00:09 [download] 77.2% of 4.40M at 112.36k/s ETA 00:09 [download] 78.6% of 4.40M at 111.41k/s ETA 00:08 [download] 80.3% of 4.40M at 110.80k/s ETA 00:07 [download] 82.3% of 4.40M at 110.30k/s ETA 00:07 [download] 84.3% of 4.40M at 108.33k/s ETA 00:06 [download] 85.7% of 4.40M at 107.62k/s ETA 00:05 [download] 87.5% of 4.40M at 107.21k/s ETA 00:05 [download] 89.5% of 4.40M at 105.10k/s ETA 00:04 [download] 90.7% of 4.40M at 106.45k/s ETA 00:03 [download] 93.2% of 4.40M at 104.92k/s ETA 00:02 [download] 94.8% of 4.40M at 104.40k/s ETA 00:02 [download] 96.5% of 4.40M at 102.47k/s ETA 00:01 [download] 97.7% of 4.40M at 103.48k/s ETA 00:01 [download] 100.0% of 4.40M at 103.15k/s ETA 00:00 [download] 100.0% of 4.40M

(不太好)。为了避免这种情况,请使用非贪婪的匹配“。+?”,或更具体的表达,如“[^] +”或Tomalak的版本。

  

fread正在读取多少正在影响正则表达式才能正常工作?

是。读取块是非常不可靠的:如果'[download]'行被分割在块边界上,它将不匹配并且将丢失。你可以:

  • 不在乎,或
  • 立即阅读整个输入,或
  • 如果输入中确实存在换行符(通常有)
  • ,则使用基于行的读取
  • 通过保留输入的最后n个字符(其中n是找到的最终匹配结束的索引)并将新的输入附加到其中来手动管理缓冲区。

至于服务器差异,我唯一能想到的是,如果其中一个服务器是Windows而另一个是a * ix,他们会对换行有什么不同的想法,这可能会导致“有新行或者不是吗?“混乱。