PHP反向正则表达式匹配

时间:2012-01-27 16:21:50

标签: php regex

我真的遇到麻烦,用PHP读取一个大的txt文件(大约12mb)。我必须匹配正则表达式,然后向后搜索匹配的正则表达式的第一个正则表达式,然后在这两个匹配之间提取字符串。这是一个真实的例子:

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

然后获取它之间的所有文本。

我无法在同一模式下使用这两个正则表达式执行preg_match,因为通过该文件,某些块具有多个273919 / SP类型并且会搞乱所有内容

我该怎么办?你有什么想法吗?

很抱歉,如果我的正则表达式很糟糕,我是新手,并且很难学习:P

编辑:

请检查代码出现的另一个表单:

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,我需要获取最后一个并在id 583.00.2012.100905-6 / 000000-000和OAB / SP 302811之间提取文本

这些数字不是固定的,所以我不能搜索OAB / SP 302811,但是OAB \ / SP \ s \ d {6}

6 个答案:

答案 0 :(得分:2)

你有两个表达式,re1和re2,你想匹配re1,然后找到它之前的第一个re2匹配,并获取它们之间的内容。

假设在re1匹配之前始终存在re2匹配,那么这相当于:匹配re2,后跟不包含任何re2匹配并捕获它的字符串,然后是re1匹配。

这可以写成:

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

如果re1为\d{6}/SP而re2为\d{3}\.\d{2}\.\d{4}\.\d{6}则为:

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

我已经将re1和re2匹配放在捕获组中,以防你想要它们的值。

答案 1 :(得分: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 :(得分:1)

我认为它实际上就像查找两个密钥/ 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]中的中间部分。因此,您可以使用end($matches[1])获取273919/SP ID的最后一个条目。你可能不需要那么多的内部文本断言,就像插图一样,以避免空行。

但实质上,你并没有“反向匹配”,而只是让它更具体的内部部分。然后,您可以按照它们在文件中出现的顺序列出您要搜索的两件事。

答案 3 :(得分: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;
  }
}

?>

答案 4 :(得分: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:

答案 5 :(得分:-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
}