当前位置:首页 > 百科

php寻找文本是否存在

服务器日志里躺着几万行请求记录,找文我对着终端窗口发呆。本否要找出所有包含特定参数的找文访问,靠肉眼翻页简直是本否自虐。PHP的找文strpos()函数就在这时候派上用场——它返回字符串第一次出现的位置,找不到就返回false。本否就这么简单,找文却比正则表达式省心得多。本否

写判断的找文时候有个坑。新手常写成if (strpos($haystack,本否 $needle)),觉得非零就是找文找到了。可如果目标文本恰好出现在开头,本否strpos()返回0,找文在PHP里0等于假,本否条件直接不成立。找文这种bug藏得深,日志里翻半天都找不到原因。正确写法是if (strpos($haystack, $needle) !== false),严格比较类型,才能把位置0和没找到区分开。

处理用户提交的搜索词,得先过滤一遍。空字符串传给strpos()会返回0,逻辑上没错,但没意义。我习惯先trim()掉首尾空格,再检查长度。真要匹配中文,strpos()按字节找,UTF-8下一个汉字占三个字节,位置数字看着别扭,但功能不受影响。

换到多字节场景,mb_strpos()更靠谱。它按字符计数,配合mb_internal_encoding('UTF-8')设置,处理中文搜索词时返回的位置才符合直觉。比如在"你好世界"里找"世界",strpos()返回6,mb_strpos()返回2。前者是字节偏移,后者是字符索引,需求决定用哪个。

性能方面,strpos()比preg_match()快一个数量级。我拿一万条日志做过测试,前者跑完不到0.1秒,后者要0.8秒左右。能用简单函数解决的问题,没必要上正则。但遇到需要忽略大小写的情况,stripos()比先strtolower()再匹配更省内存——后者会把整个字符串复制一遍。

实际项目里,我常把查找逻辑封装成一个小函数,返回布尔值。调用处只关心"有没有",不关心"在哪"。这样后续如果换成str_contains()(PHP 8.0新增),只改函数内部就行。代码可读性也更好,if (contains($text, '关键词'))比一长串strpos()判断直观得多。

最后说个冷门函数substr_count(),它统计子串出现次数,不是单纯判断存在。有时候"存在几次"比"是否存在"更有价值——比如检查用户昵称里有没有重复符号,或者统计一篇文章里某个术语出现了多少回。返回整数,0就是不存在,省去比较运算符。

文本查找这活儿,看着基础,写错的人真不少。核心就一句话:用!== false判断,别用真值判断。记住这个,能少踩一半的坑。

分享到: