【问题标题】:Is there any faster/better way instead of using preg_match in the following code? [duplicate]有没有更快/更好的方法来代替在下面的代码中使用 preg_match ? [复制]
【发布时间】:2011-07-22 10:27:28
【问题描述】:

可能重复:
How can I edit my code to echo the data of child's element where my search term was found in, in XMLReader?

此代码查找<date_iso></date_iso> 中是否存在字符串 2004,如果存在,我会从找到搜索字符串的特定元素中回显一些数据。

我想知道这是否是最好/最快的方法,因为我主要关心的是速度并且 XML 文件很大。谢谢你的想法。

这是一个 XML 示例

<entry ID="4406">
    <id>4406</id>
    <title>Book Look Back at 2002</title>
    <link>http://www.sebastian-bergmann.de/blog/archives/33_Book_Look_Back_at_2002.html</link>
    <description></description>
    <content_encoded></content_encoded>
    <dc_date>20.1.2003, 07:11</dc_date>
    <date_iso>2003-01-20T07:11</date_iso>
    <blog_link/>
    <blog_title/>
</entry>

这是代码

<?php
$books  = simplexml_load_file('planet.xml');
$search = '2004';
foreach ($books->entry as $entry) {
    if (preg_match('/' . preg_quote($search) . '/i', $entry->date_iso)) {
        echo $entry->dc_date;
    }
}
?>

这是另一种方法

<?php
$books  = simplexml_load_file('planet.xml');
$search = '2004';
$regex = '/' . preg_quote($search) . '/i';
foreach ($books->entry as $entry) {
    if (preg_match($regex, $entry->date_iso)) {
        echo $entry->dc_date;
    }
}
?>

【问题讨论】:

    标签: php xml simplexml


    【解决方案1】:

    如果您主要关心的是速度,则不应为此使用 simplexml 或任何其他基于 DOM 的 xml 解析;使用基于 SAX 的解析器。此外,如果您只想进行简单的子字符串匹配(使用 strpos),请不要使用 preg_match。

    如果速度不是您真正关心的问题,而是惯用的,请使用 XPath 2.0 实现(不知道是否有用于 PHP 的实现)或执行其他基于 XPath 的正则表达式匹配的事情 - 快速谷歌显示 exslt 选项,或更简单的基于 xpath 1.0 的字符串匹配选项。

    【讨论】:

    • 我用 SAX、XMLReader 和 SimpleXML 做了一些测试。测试是回显在 date_iso 中找到 2004 的所有 dc_date。我必须说 SAX/XMLReader 比 simplexml 太慢了......这是我尝试过的源代码 madwe by hakre codepad.org/7RerAOvB
    • XMLReader 对于像这样的简单情况来说仍然太高级了——访问者、迭代器等抽象。看看 XML Parser - 只需为 entry、dc_date 和 date_iso 元素设置一个处理程序来制作一个简单的状态机,使用 strpos 来测试子字符串匹配,你就可以开始了。像这样的方法甚至不必将整个文件读入内存——据我所知,XMLReader 可以。我想当我说“基于 SAX”时,我应该将其限定为“基于事件的 SAX 解析器”。
    • 所以为了清除我的想法,你建议我使用 XML Parser 而不是 XMLReader 来提高速度和内存性能,对吧?
    • 对。我过去曾用它来解析我不想一次全部加载到内存中的大文件。它比 SimpleXML 或任何其他 API 都低得多,但这正是它快速的原因。
    • 太好了,我想这就是我正在寻找的东西。我会找到示例/教程并尝试对其进行编码。我可能会回复你一些问题
    【解决方案2】:

    preg_match是一个正则表达式函数,如果你只需要做简单的字符串比较,通常建议不要使用正则表达式。

    您使用preg_match 的替代方法是将&lt;date-iso&gt; 内容的开头与年份进行比较:

    if ($search === substr($entry->date_iso, 0, 4))
    

    因为日期始终采用相同的格式(希望如此)并以年份开头。您还可以将 - 添加到搜索字符串中,然后与前 5 个字符进行比较。

    【讨论】:

    • 如果使用没有固定字符数的书名代替具有 4 个字符的 date_iso,您的示例有何变化?
    • 您可以使用 strpos - php.net/manual/en/function.strpos.php 进行测试
    猜你喜欢
    • 2018-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-12
    • 2020-03-14
    • 2023-04-11
    • 1970-01-01
    • 2019-12-08
    相关资源
    最近更新 更多