如何检查字符串是否包含特定单词

如何检查字符串是否包含特定单词

技术背景

在PHP编程中,经常需要检查一个字符串是否包含特定的单词或子字符串。这在文本处理、搜索功能、数据验证等场景中非常常见。不同的PHP版本提供了不同的方法来实现这一功能,同时还可以使用正则表达式来进行更精确的匹配。

实现步骤

PHP 8及以上版本

在PHP 8中,可以使用str_contains函数来检查字符串是否包含特定的子字符串。示例代码如下:

1
2
3
if (str_contains('How are you', 'are')) { 
echo 'true';
}

需要注意的是,当$needle(要搜索的子字符串)为空时,str_contains函数将始终返回true。因此,在使用之前,应先确保$needle不为空:

1
2
3
4
5
6
7
8
$haystack = 'How are you?';
$needle = '';

if ($needle !== '' && str_contains($haystack, $needle)) {
echo "This returned true!";
} else {
echo "This returned false!";
}

此外,str_contains函数是区分大小写的。

PHP 8之前的版本

可以使用strpos()函数来查找一个字符串在另一个字符串中首次出现的位置。示例代码如下:

1
2
3
4
5
6
$haystack = 'How are you?';
$needle = 'are';

if (strpos($haystack, $needle) !== false) {
echo 'true';
}

需要注意的是,使用!== false是必要的,因为strpos()可能返回0,而0是一个有效的偏移量,不能简单地使用!= false=== true来判断。

使用正则表达式

使用正则表达式可以更精确地匹配单词,避免strpos函数可能出现的误匹配问题。示例代码如下:

1
2
3
4
5
$a = 'How are you?';

if (preg_match('/\bare\b/', $a)) {
echo 'true';
}

在性能方面,strpos大约比preg_match快三倍。

多用途函数

可以将上述功能组合成一个多用途函数,包括可选择的大小写敏感性:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function FindString($needle,$haystack,$i,$word)
{ // $i should be "" or "i" for case insensitive
if (strtoupper($word)=="W")
{ // if $word is "W" then word search instead of string in string search.
if (preg_match("/\b{$needle}\b/{$i}", $haystack))
{
return true;
}
}
else
{
if(preg_match("/{$needle}/{$i}", $haystack))
{
return true;
}
}
return false;
// Put quotes around true and false above to return them as strings instead of as bools/ints.
}

处理非英语语言

\b在非英语语言中可能无法正常工作,需要直接定义表示单词边界的字符。示例函数如下:

1
2
3
4
5
6
function contains($str, array $arr) {
// Works in Hebrew and any other unicode characters
// Thanks https://medium.com/@shiba1014/regex-word-boundaries-with-unicode-207794f6e7ed
// Thanks https://www.phpliveregex.com/
if (preg_match('/(?<=[\s,.:;"\']|^)' . $word . '(?=[\s,.:;"\']|$)/', $str)) return true;
}

如果要搜索一个单词数组,可以使用以下函数:

1
2
3
4
5
6
7
8
9
10
function arrayContainsWord($str, array $arr)
{
foreach ($arr as $word) {
// Works in Hebrew and any other unicode characters
// Thanks https://medium.com/@shiba1014/regex-word-boundaries-with-unicode-207794f6e7ed
// Thanks https://www.phpliveregex.com/
if (preg_match('/(?<=[\s,.:;"\']|^)' . $word . '(?=[\s,.:;"\']|$)/', $str)) return true;
}
return false;
}

核心代码

使用str_contains函数

1
2
3
if (str_contains('How are you', 'are')) { 
echo 'true';
}

使用strpos函数

1
2
3
4
5
6
$haystack = 'How are you?';
$needle = 'are';

if (strpos($haystack, $needle) !== false) {
echo 'true';
}

使用正则表达式

1
2
3
4
5
$a = 'How are you?';

if (preg_match('/\bare\b/', $a)) {
echo 'true';
}

最佳实践

  • 在PHP 8及以上版本中,优先使用str_contains函数,因为它简洁且易于理解。
  • 在PHP 8之前的版本中,使用strpos函数时,务必使用!== false进行判断。
  • 如果需要精确匹配单词,使用正则表达式,并注意处理非英语语言的情况。
  • 在处理用户输入时,要对输入进行过滤和验证,避免正则表达式注入等安全问题。

常见问题

str_contains函数对空字符串的处理

$needle为空时,str_contains函数将始终返回true。因此,在使用之前,应先确保$needle不为空。

strpos函数返回值的判断

strpos函数可能返回0,这是一个有效的偏移量,不能简单地使用!= false=== true来判断。必须使用!== false进行判断。

正则表达式的性能问题

正则表达式的性能相对较低,尤其是在处理大量数据时。如果只是简单的子字符串匹配,优先使用strposstr_contains函数。

非英语语言的单词边界问题

\b在非英语语言中可能无法正常工作,需要直接定义表示单词边界的字符。


如何检查字符串是否包含特定单词
https://119291.xyz/posts/2025-05-13.how-to-check-if-a-string-contains-a-specific-word/
作者
ww
发布于
2025年5月13日
许可协议