2

我更喜欢使用 php 或 perl 的答案,因为我可以轻松使用它们

文件格式如下:

Name : ...
INSERT INTO (...) Values (...)
Name : ...                         <--- These are the lines I need
INSERT INTO (...) Values (...)     <--- 
<span style='color:red;'>FAILED to INSERT ...</span>
Name : ...
INSERT INTO (...) Values (...)
...

“FAILED to INSERT”跨度后面的行是我感兴趣的行。我想删除所有成功的插入,只留下 Name: 和 INSERT INTO 部分失败的行。

“名称:”和“插入...”部分不一定在一行。

这是我认为我需要匹配的伪模式:

(/Name:/)(any character)(/INSERT INTO/)(anything but not /Name:/)(/FAILED to INSERT/)

这会让我留下

Name: ...
INSERT INTO ...
<span ...> FAILED to INSERT

对于每个失败的插入

我熟悉一些正则表达式基础知识,但可以使用一些帮助。我怎么能在 perl 或 php 中做到这一点?

4

4 回答 4

4

我认为这不是正则表达式的适当任务。通读文件并逐行累积所需的信息会更清晰。

这是一个使用您提供的示例数据的 Perl 解决方案。

use strict;
use warnings;

my $info;

while (<DATA>) {
  $info = '' if /Name :/;
  $info .= $_;
  print $info if /FAILED to INSERT/;
}

__DATA__

Name : ...
INSERT INTO (...) Values (...)
Name : ...                         <--- These are the lines I need
INSERT INTO (...) Values (...)     <--- 
<span style='color:red;'>FAILED to INSERT ...</span>
Name : ...
INSERT INTO (...) Values (...)
...

输出

Name : ...                         <--- These are the lines I need
INSERT INTO (...) Values (...)     <--- 
<span style='color:red;'>FAILED to INSERT ...</span>

我希望清楚如何从文件中读取数据。如果您在命令行上传递文件名,那么您只需将循环更改为while (<>) { ... }.


编辑

对于单行命令解决方案,这个怎么样

perl -0777 -ne"/FAILED to INSERT/ and print for split /(?=Name :)/" myfile

输出

Name : ...                         <--- These are the lines I need
INSERT INTO (...) Values (...)     <---
<span style='color:red;'>FAILED to INSERT ...</span>
于 2012-04-13T19:23:56.457 回答
3

我相信@FritsvanCampen 是在正确的轨道上。与使用正则表达式不同,逐行遍历整个文件同样容易。这是使用多维数组的稍微修改的版本。(仅供参考,我不太了解 php,因此可能需要一两次调整)。

$handle = fopen("strangefile.txt", "r");

$names = array();
$name = array();
while($line = fgets($handle)) {
    if (substr($line, 0, 5) === "Name:") {
      // start a new name array
      $name = array($line);
    }
    else
    {
      // append to existing name array
      $name[] = $line;

      // check to see if the current name array is type 'error'
      if (substr($line, 0, 31) === "<span style='color:red;'>FAILED to INSERT") {
        $names[] = $name;
      }
    }
}
var_dump($names);
于 2012-04-13T19:51:33.437 回答
2

正则表达式很痛苦,这样的事情怎么样?

$handle = fopen("strangefile.txt", "r");

$collect = true;
$names = array();
while($line = fgets($handle)) {
    if (substr($line, 0, 31) === "<span style='color:red;'>FAILED to INSERT") {
        $collect = false;
    } else if ($collect && substr($line, 0, 5) === "Name:") {
        $names[] = $line;
    }
}
var_dump($names);
于 2012-04-13T19:09:20.790 回答
2

Frits van Campen一样,如果您想快速解决,正则表达式只能是解决方案的一部分,而不是整个解决方案。我在他的回答中使用了其他一些逻辑,因为它并不完全正确:

$file = new SPLFileObject("strangefile.txt");

foreach($file as $line)
{
    if (isset($buffer) && substr($line, 0, 25) === "<span style='color:red;'>") {
        echo $buffer . $line;
        unset($buffer);
        continue;
    }

    if (substr($line, 0, 5) === "Name:") {
        $buffer = '';
    }
    isset($buffer) && $buffer .= $line;
}
于 2012-04-13T19:20:02.827 回答