PHP Conference Japan 2024

substr_count

(PHP 4, PHP 5, PHP 7, PHP 8)

substr_count计算子字符串出现的次数

描述

substr_count(
    字符串 $haystack,
    字符串 $needle,
    整数 $offset = 0,
    ?整数 $length = null
): 整数

substr_count() 返回在 haystack 字符串中 needle 子字符串出现的次数。请注意,needle 区分大小写。

注意:

此函数不计算重叠的子字符串。请参见下面的示例!

参数

haystack

要搜索的字符串

needle

要搜索的子字符串

offset

开始计数的偏移量。如果偏移量为负数,则从字符串的末尾开始计数。

length

指定偏移量后搜索子字符串的最大长度。如果偏移量加上长度大于 haystack 的长度,则输出警告。负长度从 haystack 的末尾开始计数。

返回值

此函数返回一个整数

变更日志

版本 描述
8.0.0 length 现在可以为 null。
7.1.0 已添加对负 offsetlength 的支持。length 现在也可以为 0

示例

示例 #1 substr_count() 示例

<?php
$text
= 'This is a test';
echo
strlen($text); // 14

echo substr_count($text, 'is'); // 2

// 字符串缩减为 's is a test',所以输出 1
echo substr_count($text, 'is', 3);

// 字符串缩减为 's i',所以输出 0
echo substr_count($text, 'is', 3, 3);

// 生成警告,因为 5+10 > 14
echo substr_count($text, 'is', 5, 10);


// 只输出 1,因为它不计算重叠的子字符串
$text2 = 'gcdgcdgcd';
echo
substr_count($text2, 'gcdgcd');
?>

参见

  • count_chars() - 返回有关字符串中使用的字符的信息
  • strpos() - 查找子字符串在字符串中第一次出现的位 置
  • substr() - 返回字符串的一部分
  • strstr() - 查找字符串的第一次出现

添加注释

用户贡献的注释 7 个注释

58
tuxedobob
8 年前
值得注意的是,此函数出奇地快。我首先在我们的 Web 服务器上针对大约 500KB 的字符串运行它。它在 0.0000 秒内找到了我正在查找的 6 个 needle 出现。是的,它的运行速度超过了 microtime() 的测量能力。

为了挑战它,我随后在一台 2010 年的 Mac 笔记本电脑上针对一个 120.5MB 的字符串运行它。对于一个测试 needle,它在 0.0266 秒内找到了 2385 个出现。另一个测试 needle 在 0.114 秒内找到了 290 个出现。

长话短说,如果您想知道此函数是否会减慢您的脚本速度,答案可能是否定的。
12
flobi at flobi dot com
18 年前
对于任何需要此功能的人来说,使其不区分大小写很容易。只需将 haystack 和 needle 转换为相同的大小写(大写或小写)。

substr_count(strtoupper($haystack), strtoupper($needle))
3
tweston at bangordailynews dot com
9 年前
为了解决 jrhodes 指出的情况,我们可以将该行更改为

substr_count ( implode( ',', $haystackArray ), $needle );

这样

数组 (
0 => "mystringth",
1 => "atislong"
);

变为

mystringth,atislong

这使得 $needle = "that" 的计数再次为 0。
-1
jrhodes at roket-enterprises dot com
15 年前
有人建议使用

substr_count ( implode( $haystackArray ), $needle );

代替前面描述的函数,但是这有一个缺陷。例如这个数组

数组 (
0 => "mystringth",
1 => "atislong"
);

如果您正在计算 "that",则 implode 版本将返回 1,但前面描述的函数将返回 0。
-1
info at fat-fish dot co dot il
17 年前
一个用于数组 needle(多个子字符串)的简单版本
<?php

function substr_count_array( $haystack, $needle ) {
$count = 0;
foreach (
$needle as $substring) {
$count += substr_count( $haystack, $substring);
}
return
$count;
}
?>
-1
XinfoX X at X XkarlX X-X XphilippX X dot X XdeX
20 年前
另一个关于 "chris at pecoraro dot net" 发布的 "cgcgcgcgcgcgc" 示例的参考

可以使用 Perl 兼容的正则表达式及其前瞻和后顾功能来满足您的请求。

示例

$number_of_full_pattern = preg_match_all('/(cgc)/', "cgcgcgcgcgcgcg", $chunks);

的工作方式类似于 substr_count 函数。变量 $number_of_full_pattern 的值为 3,因为 Perl 兼容正则表达式的默认行为是使用字符串主题中与(子)模式匹配的字符。也就是说,指针将移动到匹配子字符串的末尾。
但是我们可以使用禁用指针移动的前瞻功能

$number_of_full_pattern = preg_match_all('/(cg(?=c))/', "cgcgcgcgcgcgcg", $chunks);

在这种情况下,变量 $number_of_full_pattern 的值为 6。
首先,会匹配字符串“cg”,并将指针移动到该字符串的末尾。然后,正则表达式向前查看是否可以匹配字符'c'。无论字符'c'是否存在,指针都不会移动。
-5
php at blink dot at
10年前
这将处理一个字符串,其中千位分隔符或小数分隔符是逗号还是句点未知。唯一导致冲突的例外情况是,只有一个逗号或句点和3个可能的小数位 (123.456 或 123,456)。一个可选参数用于处理这种情况(假设千位分隔符,假设小数分隔符,句点为小数分隔符,逗号为小数分隔符)。它假设输入字符串采用以下任何格式。

函数toFloat($pString, $seperatorOnConflict="f")
{
$decSeperator=".";
$thSeperator="";

$pString=str_replace(" ", $thSeperator, $pString);

$firstPeriod=strpos($pString, ".");
$firstComma=strpos($pString, ",");
if($firstPeriod!==FALSE && $firstComma!==FALSE) {
if($firstPeriod<$firstComma) {
$pString=str_replace(".", $thSeperator, $pString);
$pString=str_replace(",", $decSeperator, $pString);
}
else {
$pString=str_replace(",", $thSeperator, $pString);
}
}
else if($firstPeriod!==FALSE || $firstComma!==FALSE) {
$seperator=$firstPeriod!==FALSE?".":",";
if(substr_count($pString, $seperator)==1) {
$lastPeriodOrComma=strpos($pString, $seperator);
if($lastPeriodOrComma==(strlen($pString)-4) && ($seperatorOnConflict!=$seperator && $seperatorOnConflict!="f")) {
$pString=str_replace($seperator, $thSeperator, $pString);
}
else {
$pString=str_replace($seperator, $decSeperator, $pString);
}
}
else {
$pString=str_replace($seperator, $thSeperator, $pString);
}
}
return(float)$pString;
}

函数testFloatParsing() {
$floatvals = array(
"22 000",
"22,000",
"22.000",
"123 456",
"123,456",
"123.456",
"22 000,76",
"22.000,76",
"22,000.76",
"22000.76",
"22000,76",
"1.022.000,76",
"1,022,000.76",
"1,000,000",
"1.000.000",
"1022000.76",
"1022000,76",
"1022000",
"0.76",
"0,76",
"0.00",
"0,00",
"1.00",
"1,00",
"-22 000,76",
"-22.000,76",
"-22,000.76",
"-22 000",
"-22,000",
"-22.000",
"-22000.76",
"-22000,76",
"-1.022.000,76",
"-1,022,000.76",
"-1,000,000",
"-1.000.000",
"-1022000.76",
"-1022000,76",
"-1022000",
"-0.76",
"-0,76",
"-0.00",
"-0,00",
"-1.00",
"-1,00"
);

echo "<table>";
<tr>
<th>字符串</th>
<th>千位</th>
<th>小数</th>
<th>句点为小数</th>
<th>逗号为小数</th>
</tr>";

foreach ($floatvals as $fval) {
echo "<tr>";
echo "<td>" . (string) $fval . "</td>";

echo "<td>" . (float) toFloat($fval, "") . "</td>";
echo "<td>" . (float) toFloat($fval, "f") . "</td>";
echo "<td>" . (float) toFloat($fval, ".") . "</td>";
echo "<td>" . (float) toFloat($fval, ",") . "</td>";
echo "</tr>";
}
echo "</table>";
}
To Top