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



我有一个日志文件(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。此外,在给定的日期和时间,条目可能只有错误,只有关于创建的文件的消息,或者两者都有,就像我在这里显示的那样。

文件以这种方式继续。我有一个数据库,格式是:

id  itemName status
1   file     NULL

等等…

现在,我应该浏览日志文件,对于每个创建的文件,或者如果出现错误,我应该用适当的消息更新DB的最后一列:file created或error。我想搜索字符串"创建的PDF文件/Error",然后获取文件名。

我试过各种各样的东西,比如pathinfo()strpos。但是,我似乎不明白我将如何完成它。

有人能为我提供一些关于如何解决这个问题的意见吗?txt文件和数据库相当大。

注意:我提供了日志文件的第二个条目,以明确出现错误的格式不一致。我想知道我是否仍然可以在不一致的错误格式下实现我应该实现的目标。有人能在把整个问题再读一遍后帮忙吗?自从我第一次发布这篇文章以来,已经有了很多变化。

您可以使用php的explode方法将文件分解为多个单词。如果文本文件中的字段是制表符分隔的,则可以在explode(String,'t');上分解,或者如果是空格分隔的,可以在空格上分解。

然后,每个单词上的一个简单的substr(word,start_index,length)可以给你文件的名称(这里start_index应该是0)。

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

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

您可以随时参考php.net手册获得帮助。

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

// 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.php和http://php.net/manual/en/function.preg-match.php

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

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

$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
}

编辑:实际上回到您的文章,您似乎想要更新一个表而不是插入,所以您希望将查询更改为更新。您可能需要在where子句的foreach中进一步使用$file,这取决于您在数据库中存储文件名的方式(例如,如果您只存储基本名称,则可能希望在foreach中执行$file = basename($file);)。更新代码以反映这一点。

所以希望这能为你指明正确的方向。

最新更新