PHP反向正则表达式匹配

PHP反向正则表达式匹配,php,regex,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 TRIBU

在这里,我真的很难用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(regex:[0-9]{6}/SP) 向后检查代码:583.00.2012.105981(正则表达式:[0-9]{3}.[0-9]{2}.[0-9]{4}.[0-9]{6})

然后得到它之间的所有文本

我不能在同一个模式下对这两个正则表达式进行preg_匹配,因为通过该文件,一些块有多个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}

您的数据似乎有重复模式。如果是这样的话,您可以将它放入一个数组中,并单独处理每个数组元素,这有效地限制了正则表达式调用的范围

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

您的数据似乎具有重复模式。如果是这样的话,您可以将它放入一个数组中,并单独处理每个数组元素,这有效地限制了正则表达式调用的范围

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

我不明白你为什么要做一些奇怪的反向搜索。就这样做吧:

$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

我不明白你为什么要做一些奇怪的反向搜索。就这样做吧:

$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

您有两个表达式,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匹配放在这里的捕获组中,以防您也需要它们的值。

您有两个表达式,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匹配项放在这里的捕获组中,以防您也需要它们的值。

我假设它实际上非常简单,只需查找两个键/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的最后一个条目。对于内部文本,您可能不需要太多断言,正如图中所示,以避免出现空行


但从本质上讲,您并没有“反向匹配”,只是简单地使其内部更具体。然后,您可以按文件中出现的顺序列出要搜索的两个内容。

我假设这实际上很简单,只需查找两个键/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的最后一个条目。对于内部文本,您可能不需要太多断言,正如图中所示,以避免出现空行


但从本质上讲,您并没有“反向匹配”,只是简单地使其内部更具体。然后,您可以按文件中出现的顺序列出要搜索的两个内容。

您正在尝试提取每条记录的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;
  }
}

?>

您试图为每条记录提取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;
  }
}

?>


为什么必须按相反的顺序进行搜索?因为我不能在273919/SP regex的第一个匹配项中停止搜索,因为一个块可能包含多个而不是一个。因此,我必须为我遇到的每一个273919/SP regex提取这个字符串,然后返回到583.00.2012.105981 regex,寻找
AVOCADO:
PROSECCO:
键不是更好(可行吗?)?还是只需要提取单个块?您是否尝试过按自然顺序使用搜索字符串,中间有
*?
?如果您的文本块中有多个
273919/SP
您想匹配第一个还是最后一个
273919/SP
?为什么必须按相反的顺序进行搜索?因为我无法在273919/SP regex的第一次出现时停止,因为一个块可能包含多个,而不是一个。因此,我必须为我遇到的每一个273919/SP regex提取这个字符串,然后返回到583.00.2012.105981 regex,寻找
AVOCADO: