2012-01-27 35 views
1

PHPで大きなtxtファイル(約12MB)を読むのには本当に困っています。私は、正規表現に一致し、最初の別の正規表現のオカレンスを検索して、この正規表現を後方に検索してから、この2つのマッチの間の文字列を抽出する必要があります。ここで実際の例である:PHPのリバース正規表現

PROCESSO:583.00.2012.105981 
No ORDEM:01.19.2012/000154 
CLASSE:PROCEDIMENTO SUMÁRIO (EM GERAL) 
REQUERENTE:ASSETJ ASSOCIAÇÃO DOS SERVIDORES DO TRIBUNAL DE JUSTIÇA DO ESTADO DE SÃO PAULO 
ADVOGADO:273919/SP - THIAGO PUGINA 
Requerido:TIM CELULAR S/A E OUTRO 
VARA:19a. VARA CÍVEL 

PROCESSO:583.00.2012.105970 
No ORDEM:01.07.2012/000134 
CLASSE:PROCEDIMENTO ORDINÁRIO (EM GERAL) 
REQUERENTE:CARLOS NEUMANN 
ADVOGADO:79117/SP - ROSANA CHIAVASSA 
Requerido:SUL AMÉRICA SEGURO SAÚDE S/A 
VARA:7a. VARA CÍVEL 

スクリプトがこのコードを見つける必要があります:273919/SP:コードの後方(正規表現[0-9] {6}/SP) チェック:583.00.2012.105981(正規表現: [0-9] {3}。[0-9] {2}。[0-9] {4}。[0-9] {6})

そして、その間のすべてのテキストを取得します。

ファイルを介してブロックの一部が複数の273919/SPタイプを持っており、それは私ができることはすべて

と台無しになるので、私は同じパターンで、これらの正規表現の両方とするpreg_matchを行うことはできません

行う?あなたはなにか考えはありますか?

私の正規表現は安っぽいであれば、私はそれで新しいですし、それを学ぶことは非常に困難です申し訳ありません:P

EDIT:

コードが表示されていることを別のフォームを確認してください:

583.00.2012.100905-6/000000-000 - no ordem 82/2012 - Procedimento Sumário (em geral) - JOSE APARECIDO DOS 
SANTOS X SEGURADORA LIDER DOS CONSORCIOS DO SEGUROS DPVAT S/A - Fls. 79 - Demonstre o autor, por meio 
de documento idôneo (declaração de bens e renda e comprovante de pagamento), a necessidade de obtenção do benefício 
da justiça gratuita, a fim de ser cumprido o disposto no artigo 5o, LXXIV da CF. Após, tornem os autos conclusos. Int. - ADV 
GUILHERME DIAS GONÇALVES OAB/SP 302632 - ADV TIAGO RAFAEL OLIVEIRA ALEGRE OAB/SP 302811 

それは私の問題です。 OAB/SP 302632とOAB/SP 302811の2つの出現があり、最後のものを取得し、id 583.00.2012.100905-6/000000-000とOAB/SP 302811

の間でテキストを抽出する必要があります。数字は固定されていないので、OAB/SP 302811、OAB \ SP \ s \ d {6}

+0

なぜ逆の順序で検索する必要がありますか? –

+0

私は273919/SP正規表現の最初の出現で停止することができないので、ブロックには1つ以上のものが含まれている可能性があります。だから、私はこの文字列を私が遭遇するすべての273919/SP正規表現に対して抽出しなければならないし、後方に移動して583.00.2012.105981正規表現を見つけなければならない –

+1

'AVOCADO:'と 'PROSECCO:'キー?または、1つのブロックのみを抽出する必要はありますか?間に '。*? 'をつけて自然な順序で検索文字列を使ってみましたか? – mario

答えて

1

私はそれが実際にちょうど2つのキー/ IDトークンを探していると.*?代替との間でテキストブロックをフェッチするのと同じくらい簡単であると仮定します:これはあなたのデータブロックを探し

preg_match_all('~ 

    (?:^PROCESSO: \d+(?:\.\d+){3} \s*) 
    ((?:^[\w\s]+: .*    \s*)+) # multiple lines in between 
    (?:^ADVOGADO: 273919/SP   ) 

    ~mx', 
    $input, $matches 
) 
and print_r($matches); 

、となります中部を$matches[1]に返してください。だから idの最後のエントリを取得するのにend($matches[1])を使うことができます。おそらく空の行を避けるためのイラストと同じように、内側のテキストにはそれほど多くのアサーションは必要ありません。

しかし、本質的に、あなたは「逆にマッチしない」というだけでなく、内側の部分をより具体的にするだけです。次に、検索したい2つのものをファイル内の順番に並べることができます。

-1

の検索はできません。データに繰り返しパターンがあるようです。もしそうなら、explode()を配列に入れて、個々の配列要素を個別に処理して、正規表現呼び出しの範囲を効果的に制限します。

// Get data 
$file_data = get_file_contents('/path/to/my/file.txt'); 

// Explode data into chunks using repeated delimiter 
$data = explode("PROCESSO:", $file_data); 

// Process array 
foreach($data as $chunk) 
{ 
    // Perform regex functions on $chunk here 
} 
+0

すべてのものを爆発させないようにしましょう、よろしいですか?それは多くの構造を主張せず、特にこの場合、結果のチャンクから意図したデータを取り出すことが容易ではない。 – mario

+0

cillosisありがとうございますが、もう少し複雑です。それはPDFから私はtxtに抽出するだろうし、それは多くの汚い文字と無駄な文字列があります。私はそれらすべてをきれいにしようとしていますが、変化するヘッダーやフッターがたくさんあり、問題があるので、必要のないすべてのコンテンツを削除するのではなく、コンテンツデータをチェックするという可能性を考えました –

+0

@ViniciusTavaresああ、私は参照してください。だから私はこれが1回実行されていると推測している(正しく動作すると仮定して)データを解析して何かをするのだろうか? –

0
<?php 

$txt = <<<TEXT 
PROCESSO:583.00.2012.105981 
No ORDEM:01.19.2012/000154 
CLASSE:PROCEDIMENTO SUMÁRIO (EM GERAL) 
REQUERENTE:ASSETJ ASSOCIAÇÃO DOS SERVIDORES DO TRIBUNAL DE JUSTIÇA DO ESTADO DE SÃO PAULO 
ADVOGADO:273919/SP - THIAGO PUGINA 
Requerido:TIM CELULAR S/A E OUTRO 
VARA:19a. VARA CÍVEL 

PROCESSO:583.00.2012.105970 
No ORDEM:01.07.2012/000134 
CLASSE:PROCEDIMENTO ORDINÁRIO (EM GERAL) 
REQUERENTE:CARLOS NEUMANN 
ADVOGADO:79117/SP - ROSANA CHIAVASSA 
Requerido:SUL AMÉRICA SEGURO SAÚDE S/A 
VARA:7a. VARA CÍVEL 
TEXT; 

$matches = array(); 
preg_match('/[0-9]{6}\/SP(.*)[0-9]{3}.[0-9]{2}.[0-9]{4}.[0-9]{6}/s', $txt, $matches) . "\n"; 
echo $matches[1]; 
?> 

出力:

- THIAGO PUGINA 
Requerido:TIM CELULAR S/A E OUTRO 
VARA:19a. VARA CÍVEL 

PROCESSO: 
+0

「m」修飾子のポイントは何ですか? –

1

あなたはいくつかの奇妙な後方検索を行う必要があり、なぜ私は表示されません。ただ、このような何かを:

$search = 273919; // assume this would come from user input of some sort? 
preg_match('#PROCESSO:(\d{3}\.\d{2}\.\d{4}\.\d{6}).+?ADVOGADO:' . preg_quote($search, '#') . '/SP#ms', $fileContents, $matches); 
echo $matches[1]; // 583.00.2012.105981 
2

次の2つの式、RE1とRE2を持っている、とあなたはRE1一致して、その前にまずRE2の試合を見つけて、それらの間のコンテンツを取得したいです。

re1が一致する前に常にre2の一致があると仮定すると、これは次のようになります。re2と一致し、re2の一致と取り込みを含まない文字列が続くre1一致。 RE1は\d{6}/SPで、RE2は、あなたが得る\d{3}\.\d{2}\.\d{4}\.\d{6}ある場合

(?s)re2((?:(?!re2).)*?)re1 

これは、のように書くことができ

(?s)(\d{3}\.\d{2}\.\d{4}\.\d{6})((?:(?!\d{3}\.\d{2}\.\d{4}\.\d{6}).)*?)(\d{6}/SP) 

私は場合には、ここでグループをキャプチャするにRE1とRE2マッチを入れていますあなたはそれらの価値も望んでいます。

1

PROCESS0とADVOGADOの間の行を抽出する際に、レコードは新しいPROCESS0行で識別されますか?

このように非常に大きな一貫性のある書式設定されたテキストファイルの場合、私はregexpをまったく使用しません。私は標準的なファイル操作を使用し、私自身の記録保持します。

<?php 

$fh = fopen("/path/to/file.txt", "r"); 

$keep = 0; 
$buffer = ""; 

while ($line = fgets($fh, 80)) { 
    if (strpos($line, "PROCESSO:") !== FALSE) { 
    $keep = 1; 
    continue; 
    } 
    if (strpos($line, "ADVOGADO:") !== FALSE) { 
  print $buffer; // or do whatever you want with it 
    $keep = 0; 
    $buffer = ""; 
    continue; 
    } 
    if ($keep == 1) { 
    $buffer .= $line; 
    } 
} 

?>