substr_count

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

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

描述

substr_count(
    string $haystack,
    string $needle,
    int $offset = 0,
    ?int $length = null
): int

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

注意:

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

参数

haystack

要搜索的字符串

needle

要搜索的子字符串

offset

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

length

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

返回值

此函数返回一个 int

变更日志

版本 描述
8.0.0 length 现在可以为空。
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() - 查找字符串的第一次出现

添加注释

用户贡献的注释 10 个注释

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

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

简而言之,如果你想知道这个函数是否会拖慢你的脚本,答案很可能是不会。
flobi at flobi dot com
17 年前
对于任何需要此功能的人来说,使它不区分大小写很容易。只需将 haystack 和 needle 转换为相同的大小写(大写或小写)。

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

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

这样

array (
0 => "mystringth",
1 => "atislong"
);

变为

mystringth,atislong

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

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

而不是之前描述的函数,但它有一个缺陷。例如,这个数组

array (
0 => "mystringth",
1 => "atislong"
);

如果你要计算 "that",implode 版本将返回 1,而之前描述的函数将返回 0。
info at fat-fish dot co dot il
17 年前
一个用于数组针(乘以子字符串)的简单版本
<?php

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

可以使用 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' 出现了,但指针不会移动。
qeremy [atta] gmail [dotta] com
10 年前
Unicode 示例,使用“区分大小写”选项;

<?php
function substr_count_unicode($str, $substr, $caseSensitive = true, $offset = 0, $length = null) {
if (
$offset) {
$str = substr_unicode($str, $offset, $length);
}

$pattern = $caseSensitive
? '~(?:'. preg_quote($substr) .')~u'
: '~(?:'. preg_quote($substr) .')~ui';
preg_match_all($pattern, $str, $matches);

return isset(
$matches[0]) ? count($matches[0]) : 0;
}

function
substr_unicode($str, $start, $length = null) {
return
join('', array_slice(
preg_split('~~u', $str, -1, PREG_SPLIT_NO_EMPTY), $start, $length));
}

$s = 'Ümit yüzüm gözüm...';
print
substr_count_unicode($s, 'ü'); // 3
print substr_count_unicode($s, 'ü', false); // 4
print substr_count_unicode($s, 'ü', false, 10); // 1

print substr_count_unicode($s, 'üm'); // 2
print substr_count_unicode($s, 'üm', false); // 3
?>
gigi at phpmycoder dot com
15 年前
下面建议了一个用于对数组进行 substr_count 的函数,但对于更简单的过程,请使用以下函数

<?php
substr_count
( implode( $haystackArray ), $needle );
?>
chrisstocktonaz at gmail dot com
14 年前
关于任何考虑使用 zmindster at gmail dot com 贡献的代码的人

请仔细考虑该正则表达式可能出现的边缘情况,例如

$url = 'http://w3.host.tld/path/to/file/..../file.extension';
$url = 'http://w3.host.tld/path/to/file/../file.extension?malicous=....';

这将导致无限循环,例如,这可能是拒绝服务攻击的切入点。正确的修复需要额外的代码,一个快速解决办法是在不考虑清晰度或性能的情况下添加一个额外的检查

...
$i = 0;
while (substr_count($url, '../') && ++$i < strlen($url))
...

-Chris
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;
}

function 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>String</th>
<th>thousands</th>
<th>fraction</th>
<th>dec. if period</th>
<th>dec. if comma</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