字符串匹配后从文本文件中获取文件名 - PHP

时间:2012-12-04 15:55:07

标签: php strpos pathinfo

我有一个日志文件(log.txt),格式为:

=========================================
March 01 2050 13:05:00 log v.2.6 
General Option: [default] log_options.xml
========================================= 
Loaded options from xml file: '/the/path/of/log_options.xml'
printPDF started
PDF export
PDF file created:'/path/of/file.1.pdf'
postProcessingDocument started
INDD file removed:'/path/of/file.1.indd'
Error opening document: '/path/of/some/filesomething.indd':Error: file doesnt exist or no permissions 
=========================================
March 01 2050 14:15:00 log v.2.6 
General Option: [default] log_options.xml
========================================= 
Loaded options from xml file: '/the/path/of/log_options.xml'
extendedprintPDF started
extendedprintPDF: Error: Unsaved documents have no full name: line xyz

注意:每个文件名的格式为:3lettersdatesomename_LO.pdf / indd。示例:MNM011112ThisFile_LO.pdf。此外,在给定的日期和时间,条目可能只有错误,只有关于创建的文件的消息或两者都有,就像我在这里显示的那样。

文件以这种方式继续。而且,我有一个db形式:

id  itemName status
1   file     NULL

等等......

现在,我希望通过日志文件和每个创建的文件或者如果出现错误,我应该用适当的消息更新DB的最后一列:File created or Error。我想到搜索字符串“PDF file created / Error”,然后抓取文件名。

我尝试了pathinfo()strpos等各种内容。但是,我似乎无法理解我将如何完成它。

有人可以就如何解决这个问题向我提供一些意见吗? txt文件和db非常庞大。

注意:我提供了日志文件的第二个条目,以清楚显示出现错误的格式不一致。我想知道我是否仍然可以通过不一致的错误格式实现我应该达到的目的。 在再次阅读完整个问题后,有人可以帮忙吗?从我第一次发布此内容时发生了很多变化。

3 个答案:

答案 0 :(得分:3)

您可以使用php的explode方法将文件分成多个单词。 如果文本文件中的字段以制表符分隔,则可以在explode(String,'\t');上爆炸,否则如果空格分隔,则会在空格上爆炸。

然后,每个单词上的一个简单substr(word,start_index,length)可以为您提供文件名(此处start_index应为0)。

使用mysql_connect将帮助您连接到mysql数据库,或者一种非常有效的方法是使用 PDO(PHP数据对象)来使您的代码更加可靠和灵活。< / p>

另一种方法是使用preg_match方法并指定与错误消息匹配的正则表达式并解析文件名。

您可以随时参考php.net manual寻求帮助。

答案 1 :(得分:0)

所有文件都是PDF吗?如果是这样,您可以对扩展名为.pdf的文件进行正则表达式搜索。但是,如果文件名也包含在错误字符串中,则需要以某种方式排除。

// Assume filenames contain only upper/lowercase letters, 0-9, underscores, periods, dashes, and forward slashes
preg_match_all('/([a-zA-Z0-9_\.-/]+\.pdf)/', $log_file_contents, $matches);
// $matches should be an array containing each filename.
// You can do array_unique() to exclude duplicates.

编辑:请注意,$ matches将是一个多维数组,如http://php.net/manual/en/function.preg-match-all.phphttp://php.net/manual/en/function.preg-match.php

所述

要测试正则表达式,可以使用http://regexpal.com/

答案 2 :(得分:0)

好的,所以这里的主要问题是你要么没有“条目”的一致分隔符..否则你没有提供足够的信息。所以根据你提供的内容,这是我的建议。这里的主要警告是,如果没有“条目”的固定分隔符,则无法确定错误是否与文件名匹配。解决此问题的唯一方法是更好地格式化文件。此外,您还必须填写一些空白,例如您的数据库信息以及实际执行查询的方式。

$handle = fopen("log.txt", "rb");
while (!feof($handle)) {
  // get the current row 
  $row = fread($handle, 8192);

  // get file names
  preg_match('~^PDF file created:(.*?)$~',$row,$match);
  if ( isset($match[1]) ) {
    $files[] = $match[1];
  }

  // get errors
  preg_match('~^Error:(.*?)$~',$row,$match);
  if ( isset($match[1]) ) {
    $errors[] = $match[1];
  }
}
fclose($handle);

// connect to db

foreach ($files as $k => $file) {
  // assumes your table just has basename of file
  $file = basename($file);

  $error = ( isset($errors[$k]) ) ? $errors[$k] : null;

  $sql = "update tablename set status='$error' where itemName='$file'";

  // execute query
}

编辑:实际上回到您的帖子,看起来您想要更新不插入的表,因此您需要将查询更改为更新。并且您可能需要在foreach中为$子句进一步使用$ file,具体取决于您在db中存储文件名的方式(例如,如果您只存储基本名称,则可能需要{ {1}}中的{1}}。代码已更新以反映此情况。

所以希望这会指出你正确的方向。