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:" と "INSERT INTO..." の部分は、必ずしも 1 行にあるとは限りません。

これは、一致する必要があると思われる私の疑似パターンです。

(/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

これは正規表現に適したタスクではないと思います。ファイル全体を読み、必要な情報を 1 行ずつ蓄積する方が明確です。

これは、提供されたサンプル データを使用する 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 (<>) { ... }.


編集

1行のコマンドソリューションの場合、これはどうですか

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 は正しい方向に進んでいると思います。正規表現を使用する代わりに、ファイル全体を 1 行ずつループするのも同じくらい簡単です。これは、多次元配列を使用してわずかに変更されたバージョンです。(参考までに、私は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

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 に答える
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 に答える