对于早期版本的 PHP,您可以使用以下代码片段来模拟 str_contains 函数
<?php
// 基于 PHP Laravel 框架的原始代码
if (!function_exists('str_contains')) {
function str_contains($haystack, $needle) {
return $needle !== '' && mb_strpos($haystack, $needle) !== false;
}
}
?>
(PHP 8)
str_contains — 判断一个字符串是否包含另一个字符串
haystack
要搜索的字符串。
needle
在 haystack
中要搜索的子字符串。
Example #1 使用空字符串 ''
<?php
if (str_contains('abc', '')) {
echo "检查空字符串是否存在将始终返回 true";
}
?>
以上示例会输出
Checking the existence of the empty string will always return true
Example #2 显示区分大小写
<?php
$string = 'The lazy fox jumped over the fence';
if (str_contains($string, 'lazy')) {
echo "在字符串中找到了 'lazy'\n";
}
if (str_contains($string, 'Lazy')) {
echo "在字符串中找到了 'Lazy'";
} else {
echo "由于大小写不匹配,未找到 'Lazy'";
}
?>
以上示例会输出
The string 'lazy' was found in the string "Lazy" was not found because the case does not match
Note: 此函数是二进制安全的。
对于早期版本的 PHP,您可以使用以下代码片段来模拟 str_contains 函数
<?php
// 基于 PHP Laravel 框架的原始代码
if (!function_exists('str_contains')) {
function str_contains($haystack, $needle) {
return $needle !== '' && mb_strpos($haystack, $needle) !== false;
}
}
?>
基于 PHP Laravel 框架原始代码的 polyfill 具有不同的行为;
当 $needle 为 `""` 或 `null` 时
php8 的将返回 `true`;
但是,laravel 的 str_contains 将返回 `false`;
在 php8.1 中,null 已被弃用,您可以使用 `$needle ?: ""`;
用于检查字符串是否包含数组中任意一个字符串或数组中所有字符串的几个函数
<?php
function str_contains_any(string $haystack, array $needles): bool
{
return array_reduce($needles, fn($a, $n) => $a || str_contains($haystack, $n), false);
}
function str_contains_all(string $haystack, array $needles): bool
{
return array_reduce($needles, fn($a, $n) => $a && str_contains($haystack, $n), true);
}
?>
如果 $needles 是一个空数组,str_contains_all() 将返回 true。如果您认为这是错误的,请在 $needles 中显示一个不在 $haystack 中出现的字符串,然后查找“空洞真理”。
(通过交换这些函数体中的 haystacks 和 needles,您可以创建检查一个 needle 是否出现在任何/所有 haystacks 数组中的版本。)
如果您有一个不是 UTF-8 的 needle,但在 UTF-8 字符串中查找它,则此函数并不总是产生预期的结果。对于大多数人来说,这不会是一个问题,但是如果您混合使用新旧数据,特别是如果从文件中读取数据,则可能是一个问题。
这是一个类似 "mb_*" 的函数,用于搜索字符串
<?php
function mb_str_contains(string $haystack, string $needle, $encoding = null) {
return $needle === '' || mb_substr_count($haystack, $needle, (empty($encoding) ? mb_internal_encoding() : $encoding)) > 0;
}
?>
我使用 mb_substr_count() 而不是 mb_strpos(),因为 mb_strpos() 仍然会匹配部分字符,因为它正在执行二进制搜索。
我们可以将 str_contains 与上面建议的函数进行比较
<?php
// 一些 Unicode 汉字 (漢字はユニコード)
$string = hex2bin('e6bca2e5ad97e381afe383a6e3838be382b3e383bce38389');
// 一些 Windows-1252 字符 (ãƒ)
$contains = hex2bin('e383');
// ^ 当文件在 Windows 的记事本中另存为“ANSI”时,file_get_contents() 会产生相同的数据,因此这并非不切实际。这里使用 hex2bin 的唯一原因是为了混合字符集而无需使用多个文件。
// 实际存在于我们字符串中的字符。(ー)
$contains2 = hex2bin('e383bc');
echo " = 目标字符串: ".var_export($string, true)."\r\n";
echo " = 查找字符串:\r\n";
echo " + Windows-1252 字符\r\n";
echo " - 结果:\r\n";
echo " > str_contains: ".var_export(str_contains($string, $contains), true)."\r\n";
echo " > mb_str_contains: ".var_export(mb_str_contains($string, $contains), true)."\r\n";
echo " + 有效的 UTF-8 字符\r\n";
echo " - 结果:\r\n";
echo " > str_contains: ".var_export(str_contains($string, $contains2), true)."\r\n";
echo " > mb_str_contains: ".var_export(mb_str_contains($string, $contains2), true)."\r\n";
echo "\r\n";
?>
输出
= 目标字符串: '漢字はユニコード'
= 查找字符串
+ Windows-1252 字符
- 结果
> str_contains: true
> mb_str_contains: false
+ 有效的 UTF-8 字符
- 结果
> str_contains: true
> mb_str_contains: true
然而,它并非完全万无一失。例如,Windows-1252 中的 ド 将匹配上述字符串中的 ド。因此,最好还是先将参数的编码转换为相同的编码。但是,如果字符集未知/无法检测到,并且您别无选择,只能处理脏数据,这可能是最简单的解决方案。
如果单词是以下情况,则来自“me at daz dot co dot uk”的代码将不起作用
- 在字符串的开头
- 在字符串的结尾
- 在句子的结尾(如“the ox.”或“is that an ox?”)
- 在引号中
- 等等。
您应该按空格、标点符号等分割字符串,并检查结果数组是否包含您的单词,或者尝试使用如下正则表达式进行测试
(^|[\s\W])+word($|[\s\W])+
免责声明:正则表达式可能需要一些调整
private function contains(array $needles, string $type, string $haystack = NULL, string $filename = NULL) : bool {
如果 (empty($needles)) 返回 FALSE;
如果 ($filename)
$haystack = file_get_contents($filename);
$now_what = function(string $needle) use ($haystack, $type) : array {
$has_needle = str_contains($haystack, $needle);
如果 ($type === 'any' && $has_needle)
返回 ['done' => TRUE, 'return' => TRUE];
如果 ($type === 'all' && !$has_needle)
返回 ['done' => TRUE, 'return' => FALSE];
返回 ['done' => FALSE];
};
foreach ($needles as $needle) {
$check = $now_what($needle);
如果 ($check['done'])
返回 $check['return'];
}
返回 TRUE;
}
function containsAny(array $needles, string $haystack = NULL, string $filename = NULL) : bool {
返回 self::contains($needles, 'any', $haystack, $filename);
}
function containsAll(array $needles, string $haystack = NULL, string $filename = NULL) : bool {
返回 self::contains($needles, 'all', $haystack, $filename);
}
<?php
// 适用于 PHP 4 - PHP 7 的 Polyfill,可安全地与 PHP 8 一起使用
如果 (!function_exists('str_contains')) {
函数 str_contains (字符串 $haystack, 字符串 $needle)
{
返回 empty($needle) || strpos($haystack, $needle) !== false;
}
}