在字符串中查找子字符串的所有匹配项

我需要解析一个 HTML 文档,并在其中找到字符串 asdf的所有匹配项。

目前我已经将 HTML 加载到一个字符串变量中。我只需要字符位置,这样我就可以循环遍历列表,以返回字符串后面的一些数据。

函数只返回出现的 第一。返回它们的 所有怎么样?

101580 次浏览

如果不使用正则表达式,这样的方法应该可以用来返回字符串位置:

$html = "dddasdfdddasdffff";
$needle = "asdf";
$lastPos = 0;
$positions = array();


while (($lastPos = strpos($html, $needle, $lastPos))!== false) {
$positions[] = $lastPos;
$lastPos = $lastPos + strlen($needle);
}


// Displays 3 and 10
foreach ($positions as $value) {
echo $value ."<br />";
}

使用 preg_match_all查找出现的 所有

preg_match_all('/(\$[a-z]+)/i', $str, $matches);

进一步参考检查 这个链接

最好使用 substr_count。查看 Php.net

这可以通过使用 Strpos ()函数来完成。下面的代码是使用 for 循环实现的。这段代码非常简单并且非常直接。

<?php


$str_test = "Hello World! welcome to php";


$count = 0;
$find = "o";
$positions = array();
for($i = 0; $i<strlen($str_test); $i++)
{
$pos = strpos($str_test, $find, $count);
if($pos == $count){
$positions[] = $pos;
}
$count++;
}
foreach ($positions as $value) {
echo '<br/>' .  $value . "<br />";
}


?>
function getocurence($chaine,$rechercher)
{
$lastPos = 0;
$positions = array();
while (($lastPos = strpos($chaine, $rechercher, $lastPos))!== false)
{
$positions[] = $lastPos;
$lastPos = $lastPos + strlen($rechercher);
}
return $positions;
}

可以重复调用 strpos函数,直到找不到匹配。必须指定偏移量参数。

注意: 在下面的示例中,搜索从 下一个字符开始,而不是从前一次匹配的结尾开始。根据这个函数,aaaa包含 中出现的子字符串 aa,而不是两个。

function strpos_all($haystack, $needle) {
$offset = 0;
$allpos = array();
while (($pos = strpos($haystack, $needle, $offset)) !== FALSE) {
$offset   = $pos + 1;
$allpos[] = $pos;
}
return $allpos;
}
print_r(strpos_all("aaa bbb aaa bbb aaa bbb", "aa"));

产出:

Array
(
[0] => 0
[1] => 1
[2] => 8
[3] => 9
[4] => 16
[5] => 17
)

简单的 Strpos _ all ()函数。

function strpos_all($haystack, $needle_regex)
{
preg_match_all('/' . $needle_regex . '/', $haystack, $matches, PREG_OFFSET_CAPTURE);
return array_map(function ($v) {
return $v[1];
}, $matches[0]);
}

用法: 像针一样简单的线。

$html = "dddasdfdddasdffff";
$needle = "asdf";


$all_positions = strpos_all($html, $needle);
var_dump($all_positions);

产出:

array(2) {
[0]=>
int(3)
[1]=>
int(10)
}

或者用正则表达式作为针。

$html = "dddasdfdddasdffff";
$needle = "[d]{3}";


$all_positions = strpos_all($html, $needle);
var_dump($all_positions);

产出:

array(2) {
[0]=>
int(0)
[1]=>
int(7)
}

SalmanA 有一个很好的答案,但是请记住使您的代码多字节安全。要使用 UTF-8获得正确的位置,请使用 mb _ strpos 而不是 strpos:

function strpos_all($haystack, $needle) {
$offset = 0;
$allpos = array();
while (($pos = mb_strpos($haystack, $needle, $offset)) !== FALSE) {
$offset   = $pos + 1;
$allpos[] = $pos;
}
return $allpos;
}
print_r(strpos_all("aaa bbb aaa bbb aaa bbb", "aa"));
<?php
$mainString = "dddjmnpfdddjmnpffff";
$needle = "jmnp";
$lastPos = 0;
$positions = array();


while (($lastPos = strpos($html, $needle, $lastPos))!== false) {
$positions[] = $lastPos;
$lastPos = $lastPos + strlen($needle);
}


// Displays 3 and 10
foreach ($positions as $value) {
echo $value ."<br />";
}
?>

另一种解决方案是使用 explode():

public static function allSubStrPos($str, $del)
{
$searchArray = explode($del, $str);
unset($searchArray[count($searchArray) - 1]);
$positionsArray = [];
$index = 0;
foreach ($searchArray as $i => $s) {
array_push($positionsArray, strlen($s) + $index);
$index += strlen($s) + strlen($del);
}
return $positionsArray;
}