Php 将数组的值与字符串匹配

Php 将数组的值与字符串匹配,php,foreach,preg-match,string-matching,array-difference,Php,Foreach,Preg Match,String Matching,Array Difference,我正在做一个小项目,我需要一些帮助。我有一个包含150000行的CSV文件(每行有10列数据)。我使用fscvread读取文件,在循环过程中,我希望将每行的一列(称为stringx)与10000字的数组进行匹配。如果stringx中存在10000个单词中的任何一个,则使用preg_replace将其删除 现在一切都好了。我一切都很好,但问题是,太慢了 我尝试了两种方法来匹配数组。 1) 我使用explode(“,$stringx)将stringx转换为数组,然后使用array_diff($arr

我正在做一个小项目,我需要一些帮助。我有一个包含150000行的CSV文件(每行有10列数据)。我使用fscvread读取文件,在循环过程中,我希望将每行的一列(称为stringx)与10000字的数组进行匹配。如果stringx中存在10000个单词中的任何一个,则使用preg_replace将其删除

现在一切都好了。我一切都很好,但问题是,太慢了

我尝试了两种方法来匹配数组。 1) 我使用explode(“,$stringx)将stringx转换为数组,然后使用array_diff($array_stringx,$array_10000); 2) 在$array_10000上使用foreach,在$stringx上使用preg_replace

方法1大约需要60秒来遍历200行数据,方法2可以在60秒内循环500行数据

有更好的方法吗

再一次,我在寻找一种有效的方法(基本上)将10000个单词的数组与150000个字符串进行数组区分,一次一个


非常感谢您的帮助。

您的10000字数组是否已排序?如果没有,请尝试先对其进行排序


编辑:好的,因为它已经排序了,我猜PHP的array_搜索可能没有进行二进制搜索,所以我会寻找一个二进制搜索实现并使用它。如果它确实只是一个线性搜索,那么你会得到一个数量级的速度增加。

PHP不是速度的语言,但我想你知道这一点。在我正在编写的一个项目中,我必须做类似的事情,我正在用PHP编写一个文件,然后使用Matlab单机版读取该文件,处理它并将其输出到另一个文件


您也可以这样做,并用C编写一个与
array_diff()
相同的小程序。虽然我还没有做过任何测试,但我认为会有很大的不同。

不分解stringx,对$array\u 10000中的每个单词进行一次测试怎么样

像这样:

foreach ($array_10000 as $word)
{
    if (stripos($stringx, $word) !== false)
    {
        // do your stuff
    }
}

我没有测试过这个,但我突然想到:

您可以尝试使用正则表达式对文件进行预解析,以获得要筛选的150000个单词(基于列分隔符),然后您可以进行文本替换,根据这些单词选择最佳函数


我希望有帮助!干杯

以下只是一种选择。它可能满足您的要求,也可能不满足您的要求

在我的笔记本电脑上,它每秒执行84次运算,包含10k单词字典和15k字符串

缺点是它不会删除单词周围的空格

$wordlist只是一行,每个行有一个单词,可以是一个文件

$dict = array_flip(preg_split('/\n/',$wordlist));

function filter($str,$dict) {
  $words = preg_split('/\s/',$str);
  sort($words);
  $words = array_unique($words);

  foreach ($words as $word) {
    if (key_exists($word,$dict)) {
        $removeWords[] = '/\b' . $word . '\b/';
    }
  }
  return preg_replace($removeWords, '', $str);
}
另一个执行速度稍快的示例(107ops/s,15kb字符串和10k单词字典)


您只需执行
foreach
内爆操作即可

$words = array("one","two", "three");
$number = 0;
foreach ($words as $false_array)
{
$number += 1;
$array[$number] = $false_array;
echo "Added ". $false_array . ". ";
}
foreach ($words as $false_array)
{
echo "Array Contains " . $false_array . ". ";
}
如果在php中执行此操作,您将得到:

添加了一个。加了两个。加了三个。数组包含一个。数组包含两个。数组包含三个元素。

听起来数据库是最好的选择。您的字典需要的不是数组。可以加快字典查找时间的东西。内存消耗充其量只是边际。Peter您能详细说明一下吗?您是否至少对代码进行过一次分析,以确保瓶颈是代码的这一部分?二进制搜索、纯字符串等。优化查找速度而不是内存消耗。您可能需要对字典进行排序,甚至可能需要对它进行分组。是的,它是按字母顺序排序的。foreach($array\u 10000 as$city){$stringx=preg\u replace(“/\b($city)\b/i,”,“$stringx);}这正是我所做的,每分钟大约有500个关键字,这太慢了。您使用的是preg\u replace,众所周知,匹配正则表达式通常比较慢。使用stripos检查事件,然后在发现事件时应用正则表达式可能会快一点,尽管我还没有测试过它。这看起来非常棒。问:字典中的一些行实际上是两个单词,例如Santa Cruz。由于该函数将$str分解为一个数组,因此Santa和Cruz将成为to键,然后在匹配中作为false返回。啊,是的。。当然我还没有时间解决这个问题。但这改变了一些事情
$words = array("one","two", "three");
$number = 0;
foreach ($words as $false_array)
{
$number += 1;
$array[$number] = $false_array;
echo "Added ". $false_array . ". ";
}
foreach ($words as $false_array)
{
echo "Array Contains " . $false_array . ". ";
}