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

Posted

技术标签:

【中文标题】字符串匹配后从文本文件中获取文件名 - PHP【英文标题】:Getting the file name from a text file after string matching - PHP 【发布时间】:2012-11-22 07:22:40 【问题描述】:

我有一个日志文件 (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 的最后一列:文件创建或错误。我想搜索字符串“PDF 文件已创建/错误”,然后获取文件名。

我尝试过各种方法,例如 pathinfo()strpos。但是,我似乎无法理解我将如何完成它。

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

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

【问题讨论】:

您可以在日志中发布该行的格式而不是“更多信息”吗?如果你需要文本处理,你必须先找到一个模式。 您能否发布至少一整行的错误信息?然后我们可以看到匹配的正则表达式。如果您可以在文件中发布大约 10 条不同的错误行,那就太好了 使文件格式更清晰。文件就这样继续下去。对于某些日期/时间,创建了多个 PDF 和错误。创建每个 PDF 后,都会删除 .indd 文件。 【参考方案1】:

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

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

使用 mysql_connect 将帮助您连接到 mysql 数据库,或者使用 PDO (PHP Data Objects) 使您的代码更加可靠和灵活。

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

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

【讨论】:

【参考方案2】:

所有文件都是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.php 和 http://php.net/manual/en/function.preg-match.php 所述

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

【讨论】:

请查看我所做的编辑。现在更清楚了,log.txt 包含什么。【参考方案3】:

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

$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

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

所以希望这会为您指明正确的方向。

【讨论】:

请查看我所做的编辑。现在更清楚了,log.txt 包含什么。 好吧,我提供的内容仍然可以与您所拥有的内容“工作”,但同样需要注意的是我已经提到过。您提供了我们文本文件的一个“条目”,显示了有关文件、错误等的信息。但是在您的日志文件中是否有分隔每个“条目”的东西,例如一行 * 或其他东西,或者是这样直接进入下一个条目? 另外,您并没有明确说明您真正想用什么来更新您的数据库。您是想用产生的错误更新“状态”列,还是一些通用消息或什么?当人们说“清楚你想要什么”时,这意味着显示一个示例,说明您实际希望从日志文件中的条目中提取的内容、您希望在数据库中实际看到的内容等。 请注意文件格式中的 ===。这就是每个条目的开始方式。另外,请阅读更新后的说明。 db 的最后一列可以更新为“文件创建”或“遇到错误”,视情况而定。 我已更新 pdf 和 indd 文件的正确格式。记住我最近的 2 个 cmets,您的建议是否仍然适用于我现在所做的更改?

以上是关于字符串匹配后从文本文件中获取文件名 - PHP的主要内容,如果未能解决你的问题,请参考以下文章

如果前缀是非常大的文件中的某个字符串,则在括号之间获取/匹配文本[关闭]

输入参数后从 C# 中的外部类获取连接字符串

无法匹配和替换文本文件中的 " 和 ' 字符

如何在 PHP 中获取字符串的字节值?

Java - 从 .text 文件中查找匹配的字符串

Java中的字符串搜索算法