正在解析 XML 和 PHP 中的 TXT 文件

Parsing XML and TXT files in PHP

我有一个 Text.xml 文件,其中包含一些文本和本文中的参考书目。它看起来像这样:

Text.xml

<p>…blabla S.King (1987). Bla bla bla J.Doe (2001) blabla bla J.Martin (1995) blabla…</p>

我有一个 Reference.txt 文件,其中包含书目参考文献列表和每个参考文献的 ID 号。它看起来像这样:

Reference.txt

b1#S.King (1987)
b2#J.Doe (2001)
b3#J.Martin (1995)

我想找到 Reference.txt 中的所有参考书目到 Text.xml,然后添加 ID 为 的标签。目标是TextWithReference.xml谁必须长这样:

TextWithReference.xml

<p>…blabla <ref type="biblio" target=“b1”>S.King (1987)</ref>. Bla bla bla <ref type="biblio" target=“b2”>J.Doe (2001)</ref> blabla bla <ref type="biblio" target=“b3”>J.Martin (1995)</ref> blabla…</p>

为此,我使用了一个php文件。

搜索&Replace.php

<?php
$handle = fopen("Reference.txt","r");
while(!feof($handle))
{
    $ligne = fgets($handle,1024);
    $tabRef[] = $ligne;
}   
fclose($handle);

$handleXML = fopen("Text.xml","r");
$fp = fopen("TextWithReference.xml", "w");
while(!feof($handleXML))
{
    $ligneXML = fgets($handleXML,2048);
        for($i=0;$i<sizeof($tabRef);$i++)
        {
            $tabSearch = explode('/#/',$tabRef[$i]);
            $xmlID = $tabSearch[0];
            $searchString = trim($tabSearch[1]);
            if(preg_match('/$searchString/',$ligneXML))
            {
                $ligneXML = preg_replace('/($searchString)/','/<ref type=\"biblio\" target=\"#$xmlID\">\0</ref>/',$ligneXML);
            }

        }
    fwrite($fp, $ligneXML);
}
fclose($handleXML);
fclose($fp);

?>

问题是这个php脚本只是在TextWithReference.xml中复制Text.xml,没有识别参考书目,也没有添加标签……

非常感谢您的帮助!

你的代码有很多问题。

  1. 搜索字符串包含正则表达式中的特殊字符,例如括号。如果你想从字面上匹配它们,你需要转义它们。 preg_quote 函数执行此操作。

  2. 您的文件读取循环不正确。 while (!feof()) 不是通读文件的正确方法,因为直到 after 才设置 EOF 标志。因此,您将多花一些时间来完成这些循环。正确的写法是 while ($ligne = fgets()).

  3. 您在尝试替换 $searchString$xmlID 的字符串周围有单引号。变量仅在双引号内被替换。参见 What is the difference between single-quoted and double-quoted strings in PHP?

  4. 您不需要在 preg_replace.

  5. 中的替换字符串周围放置 / 分隔符
  6. 每次处理 Text.xml 中的一行时,展开 trim 并从 Reference.txt 中转义行是低效的。在阅读 Reference.txt.

  7. 时做一次
  8. 在替换字符串中,使用 [=22=] 替换源中匹配的文本。 [=23=] 是不推荐的过时方法。

  9. 您不需要在正则表达式中的搜索字符串周围加上括号,因为您没有在替换中使用 </code> 捕获组。因为它围绕着整个正则表达式,所以它与 <code>[=22=].

  10. 相同

这是工作重写:

<?php
$handle = fopen("Reference.txt","r");
$tabRef = array();
while($ligne = trim(fgets($handle,1024))) {
    list($xmlID, $searchString) = explode('#', $ligne);
    $tabRef[] = array($xmlID, preg_quote($searchString));
}   
fclose($handle);

$handleXML = fopen("Text.xml","r");
$fp = fopen("TextWithReference.xml", "w");
while($ligneXML = fgets($handleXML,2048)) {
    foreach ($tabRef as $tabSearch) {
        $xmlID = $tabSearch[0];
        $searchString = $tabSearch[1];
        if(preg_match("/$searchString/",$ligneXML)) {
            $ligneXML = preg_replace("/$searchString/","<ref type=\"biblio\" target=\"#$xmlID\">[=10=]</ref>",$ligneXML);
        }
    }
    fwrite($fp, $ligneXML);
}
fclose($handleXML);
fclose($fp);

?>

另一项改进利用了使用数组作为 preg_replace 的搜索和替换参数的能力,而不是使用循环。读取 Reference.txt 时,在那里创建正则表达式和替换字符串,并将它们分别放入一个数组中。

<?php
$handle = fopen("Reference.txt","r");
$search = array();
$replacement = array();
while($ligne = trim(fgets($handle,1024))) {
    list($xmlID, $searchString) = explode('#', $ligne);
    $search[] = "/" . preg_quote($searchString) . "/";
    $replacement[] = "<ref type=\"biblio\" target=\"#$xmlID\">[=11=]</ref>";
}   
fclose($handle);

$handleXML = fopen("Text.xml","r");
$fp = fopen("TextWithReference.xml", "w");
while($ligneXML = fgets($handleXML,2048)) {
    $ligneXML = preg_replace($search,$replacement,$ligneXML);
    fwrite($fp, $ligneXML);
}
fclose($handleXML);
fclose($fp);

?>