php - strpos是在大文本中搜索字符串的最快方法吗?

21
if (strpos(htmlentities($storage->getMessage($i)),'chocolate')) 

你好,我正在使用gmail oauth访问来查找电子邮件地址中特定文本字符串。是否有比上述代码中使用strpos更快、更有效地查找文本实例的方法?我应该使用哈希技术吗?


6
必须使用strpos()函数的严格比较运算符。这是因为该函数可能返回整数0,这意味着字符串'chocolate'在字符串开头找到了。如果你按照你已经有的语句,这将被评估为FALSE。正确的写法应该是if (strpos(htmlentities($storage->getMessage($i)), 'chocolate') !== FALSE) - chigley
2
你为什么要使用 htmlentities()?它会拖慢所有的速度。 - NullUserException
因为我也在搜索它是否在HTML中 - 如果我删除了htmlentities标记,它会考虑链接URL吗? - Bob Cavezza
如果我省略了htmlentities,那么<a href="http://chocoloatefactory.com">Bob's Site</a>是否仍然返回true? - Bob Cavezza
htmlentities函数只会改变像引号这样的特定字符,它最好是确保在你正在搜索的字符串中这些字符也没有被编码,并且在这种情况下不使用该函数。对于你的示例字符串“chocolate”,实体没有任何影响。 - jjrv
@Bob 没有区别。在你的例子中,strpos 无论是否使用 htmlentities() 都可以找到 chocoloate(错别字)和 Site - NullUserException
3个回答

35

根据 PHP 手册,是的-strpos()是确定一个字符串是否包含另一个字符串的最快方法。

注意:

如果您只想确定某个 needle 是否出现在 haystack 中,请改用速度更快、占用更少内存的函数 strpos()。

这段话在任何关于其他字符串比较器的 php.net 文章中都会被引用(我从 strstr() 的文章中摘录了这个例子)。

尽管有两个更改应该对您的陈述进行。

if (strpos($storage->getMessage($i),'chocolate') !== FALSE)
这是因为if(0)会评估为false(因此不会运行),但是如果needle(针)在haystack(干草堆)的开头(位置0)处,strpos()可能会返回0。另外,删除htmlentities()将使您的代码运行速度更快。 htmlentities()所做的就是使用其适当的HTML等效字符替换某些字符。例如,它将每个&替换为&amp; 可以想象,单独检查字符串中每个字符并替换其中许多字符需要额外的内存和处理器功率。而且,如果您只计划进行文本比较,则这是不必要的。例如,比较以下语句:
strpos('Billy & Sally', '&'); // 6
strpos('Billy &amp; Sally', '&'); // 6
strpos('Billy & Sally', 'S'); // 8
strpos('Billy &amp; Sally', 'S') // 12

或者,在最糟糕的情况下,您甚至可能导致某些真实的事情被评估为假。

strpos('<img src...', '<'); // 0
strpos('&lt;img src...','<'); // FALSE
为了避免这种情况,你最终将使用更多的HTML实体。
strpos('&lt;img src...', '&lt;'); // 0

不过,正如您可以想象的那样,这不仅让编码变得烦人而且变得冗余。最好完全排除HTML实体。通常只有在输出文本时才使用HTML实体,而不是进行比较。


2

strpospreg_match和其他替代方案在这种情况下可能更快,最好的想法是使用实际示例数据进行一些基准测试,看看对您的需求最好的是什么,尽管这可能有点过头了。在性能开始成为问题之前,不要太担心性能。


这已经有点成问题了。我正在尝试快速搜索用户电子邮件收件箱中的字符串,但每个电子邮件的排序需要大约2秒钟。我希望将这个数字降至至少半秒钟。 - Bob Cavezza
你确定瓶颈在 strpos 函数,还是在收件箱搜索上吗?如果你使用 imap,请告诉我,我可能能够提供更多帮助。 - neopickaze

-1

strpos() 返回字符串第一次出现的开始位置,如果没有匹配则返回Null,因此语句非常实用。

if (!is_null(strpos($storage->getMessage($i),'chocolate'))) {}

也许你应该考虑重新格式化你的帖子,这样更容易理解哪些是代码,哪些不是。 - norok2
2
strpos函数从不返回null,它返回false - undefined
1
strpos函数从不返回null,它返回false - Christian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接