preg_match() + 正则表达式在 TXT 文件中不起作用


preg_match() + regex does not work in TXT file

示例 1:

我有一个PDF文档,并在线使用PDF解析器(www.pdfparser.org(将其所有内容转换为文本格式。抢救了TXT文件中的内容(手动(并尝试使用正则表达式过滤一些数据,一切正常。


示例 2:

为了自动化该过程,我下载了PDF解析器API,并制作了一个遵循以下规则的脚本:

1( 使用 ParseFile (( API 方法转换 PDF 文本.
2( 保存 TXT.
的内容3( 尝试使用正则表达式过滤掉此 TXT。


示例 1 -> 它有效并返回我:

array (size = 2)
   'mora_dia' =>
     array (size = 1)
       0 => string 'R $ 3.44' (length = 7)
   'fine' =>
     array (size = 1)
       0 => string 'R $ 17.21' (length = 8)

示例 2 -> 它不起作用。

array (size = 2)
   'mora_dia' =>
     array (size = 0)
       empty
   'fine' =>
     array (size = 0)
       empty
  • 来自两个 TXT 的数据相等,但由于在第二个示例中不起作用? *(我试图在不保存在 TXT 中的情况下执行此操作,但没有奏效(

以下是我的两个示例的代码:

示例 1:

$data = file_get_contents('exemplo_01.txt');
$regex = [
    'mora_dia' => '/R'$ [0-9]{1,}'.[0-9]{1,}/i',
    'multa'    => '/R'$ [0-9]{1,}',[0-9]{1,}/i'
];
foreach($regex as $title => $ex)
{
    preg_match($ex, $data, $matches[$title]);
}
var_dump($matches);

示例 2:

$parser = new 'Smalot'PdfParser'Parser();
    $pdf = $parser->parseFile($PDFFile);
    $pages = $pdf->getPages();
    foreach ($pages as $page) {
        $PDFParse = $page->getText();
    }
    $txtName = __DIR__ . '/files/Txt/' . md5(uniqid(rand(), true)) . '.txt';
    $file  = fopen($txtName, 'w+');
    fwrite($file, $PDFParse);
    fclose($file);
    $dataTxt = file_get_contents($txtName);
    $regex = [
        'mora_dia' => '/R'$ [0-9]{1,}'.[0-9]{1,}/i',
        'multa'    => '/R'$ [0-9]{1,}',[0-9]{1,}/i'
    ];
    foreach($regex as $title => $ex)
    {
        preg_match($ex, $dataTxt, $matches[$title]);
    }

您手动复制和粘贴输出文本的操作似乎实际上已更改其内容。 根据 pastebin 输出,直接到文件版本包含不间断空格字符,而不是常规空格。 不间断空格具有十六进制代码 0xA0 ascii 160,而不是常规空格,十六进制0x20 ascii 32。

实际上,看起来直接到文件示例中的所有空格字符都是不间断的0xA0空格。

若要将正则表达式修改为能够容纳任一类型的空格,可以将十六进制代码与常规空格字符' '一起放入[]字符类中,如[ 'xA0]中所述,以匹配任一类型。 此外,您将需要 /u 标志才能使用 unicode。

$regex = [
    'mora_dia' => '/R'$[ 'xA0][0-9]{1,}'.[0-9]{1,}/iu',
    'multa'    => '/R'$[ 'xA0][0-9]{1,},[0-9]{1,}/iu'
];

(注意,,逗号不需要反斜杠转义(

使用您的原始糊剂作为输入,这可以正常工作:

$str = file_get_contents('http://pastebin.com/raw.php?i=H7D5xJBH');
preg_match('/R'$[ 'xa0][0-9]{1,}'.[0-9]{1,}/ui', $str, $matches);
var_dump($matches);
// Prints:
array(1) {
  [0] =>
  string(8) "R$ 3.44"
}

另一种解决方案可能是在应用原始正则表达式之前,将整个文本中的不间断空格替换为常规空格:

// Replace all non-breaking spaces with regular spaces in the
// text string read from the file...
// The unicode non-breaking space is represented by 00A0
// and both are needed to replace this successfully.
$dataTxt = str_replace("'x00'xA0", " ", $dataTxt);

每当输入您希望相同时,在视觉上看起来是相同的,请务必使用能够显示每个字符十六进制代码的工具对其进行检查。在这种情况下,我将 pastebin 中的样本复制到文件中,并使用 Vim 检查它们,其中我为光标下方的字符设置了十六进制和 ascii 显示。

 $PDFParse ='';
 foreach ($pages as $page) {
     $PDFParse = $PDFParse.$page->getText();
 }

如果 PDFParse 是字符串,并且在 fwrite 之后尝试 fflush($file(