【问题标题】:Best way to find matches of several substrings in string? [closed]在字符串中查找多个子字符串匹配的最佳方法? [关闭]
【发布时间】:2015-10-03 05:31:27
【问题描述】:

我有$a=array('1str','2str','3str')$str ='123 2str 3str 1str'
并尝试做一件简单的事情——在 $str 中找到$a 的每个项目的位置。

使用循环和strpos 很容易完成,但我很好奇获得职位的最佳(实际上是简短)方法是什么?

实际上我需要在字符串 (2str) 中找到最近的项目

【问题讨论】:

  • 如果strpos 足够简单并且可以工作,那么我建议你坚持下去。如果性能是一个问题,那么您应该为自己编写一个基准测试并查看您的实现如何在多次迭代中保持稳定。你现在正在做的一些代码会让其他人了解你正在使用的东西。

标签: php string search strpos


【解决方案1】:

你可以用array_map()这样做

$a = array('1str', '2str', '3str');
$str ='123 2str 3str 1str';

function my_strpos($needle) {
    global $str;
    return strpos($str, $needle);
}

$positions = array_map('my_strpos', $a);

print_r($positions); 给出:

Array
(
    [0] => 14
    [1] => 4
    [2] => 9
)

【讨论】:

  • 足够好。谢谢
  • 我想他想要$a[array_keys($positions, min($positions))[0]]
【解决方案2】:

如果你需要所有的偏移量,也可以使用preg_match_all函数和标志PREG_OFFSET_CAPTURE

if(preg_match_all('/'.implode('|', $a).'/', $str, $out, PREG_OFFSET_CAPTURE))
  print_r($out[0]);

如果您需要匹配 \b word boundaries 或使用 i flag 进行无大小写匹配,则很有用。

正如@mike.k 评论的那样:如果$a 包含characters with special meaning inside a regex pattern,则需要先转义:array_map(function ($v) { return preg_quote($v, "/"); }, $a)


要获得最接近开始的那个,不需要所有偏移量。可以使用 preg_matchsimple pattern 1str|2str|3str (see test at eval.in) 来做到这一点。

if(preg_match('/'.implode('|', $a).'/', $str, $out, PREG_OFFSET_CAPTURE))
  echo "The substring that's closest to start is \"".$out[0][0]."\" at offset ".$out[0][1];

最接近 start 的子字符串是偏移 4 处的“2str”


如果你根本不需要偏移量/正则表达式,第一个匹配的另一个想法:使用usort by pos 排序

usort($a, function ($x, $y) use (&$str) {
  return (strpos($str, $x) < strpos($str, $y)) ? -1 : 1;
});

echo $a[0]; > 2str (使用 usort 的匿名函数至少需要 PHP 5.3

【讨论】:

  • 不错!忘记了那面旗帜。一项改进:将$a 更改为array_map('preg_quote', $a)
  • 没错,这可能需要事先使用foreach
  • 在我的情况下,应该有另一个循环来查找最接近字符串开头的结果
  • @elDude 你的意思是最接近字符串开头的那个?查看更新的答案。
  • 如果您的意思是 $out[0] 是最接近的子字符串,那么这就是我要查找的内容
猜你喜欢
  • 2016-07-01
  • 1970-01-01
  • 2020-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多