【问题标题】:Replace strings in a file from an array in PHP从PHP中的数组替换文件中的字符串
【发布时间】:2014-02-23 15:20:58
【问题描述】:

这是一个棘手的问题...我正在尝试替换我保存在数组中的文件中的一些字符串。 因为有很多文件……我一直在努力寻找最快的方法。 我试过这个(效果很好),但速度很慢。

  • 首先解析所有文件并得到一个我想要的值的数组 改变(假设是 500)。
  • 然后我写了一个 foreach 循环来逐个解析文件。
  • 然后在其中,另一个 foreach 循环逐个遍历这些值 preg_replacing 文件中任何出现的数组值。

这需要很长时间,因为并非所有文件都需要使用 500 个数组元素进行解析。 所以我现在像这样更改代码:

  • 解析每个文件并创建一个包含我要替换的值的数组。
  • 再次在文件中搜索所有出现的每个数组值并替换它。
  • 保存文件

我认为这会比旧方法快得多...我现在遇到的问题是读/写循环和数组循环... 我想尽可能快地做到这一点......因为会有很多文件要解析,有些文件有 100 多个值。 到目前为止,我在一个函数中得到了这个。

function openFileSearchAndReplace($file)
{
  $holdcontents = file_get_contents($file);
  $newarray = makeArrayOfValuesToReplace($holdcontents);
  foreach ($newarray as $key => $value) {
    $replaceWith = getNewValueFor($value);
    $holdcontent = preg_replace('/\\b'.$value.'\\b/', $replaceWith, $holdcontents);
   }
   file_put_contents($file, $holdcontent, LOCK_EX);  //Save and close
}

现在,这不起作用...它只是更改 1 个值,只是因为我在 foreach 之外有 file_put_contentsfile_get_contents。 (更不用说它替换了它不应该替换的值。可能导致读/写在循环之外。)我必须把它们放在里面才能工作..但这会很慢..因为每次需要 3-4 秒文件进行更改,因为数组中有很多元素。

如何“打开文件”、“阅读”、“先更改 ALL 值”、“然后保存关闭文件”,这样我才能转到下一个。

编辑: 也许我没有很好地解释它我不知道......或者这太复杂了......我必须解析值数组......我无法避免......但不是(在每个循环),我打开文件搜索并替换1个值,关闭文件.....我想这样做: 打开文件,以数组或字符串或其他形式获取内容。对于所有值,我一直用等效值替换文本,并且当所有值都完成后......该数组或字符串写入文件。所以我只打开/关闭文件一次。而不是一直等待 php 读/写/关闭。

-谢谢

【问题讨论】:

  • 这些数组项分别对应什么?行?,我认为在这些文件上运行类似sed 的东西会比读取->解析->处理->保存快得多
  • 数组是单词……例如,首先我解析文件并从文件中收集所有水果单词……我想用蔬菜单词替换……每个都被替换通过它的等价物。 getNewValueFor() 为我做这件事。用土豆代替单词:apple。我使用 preg_replace('/\\b'.$value.'\\b/' 只匹配该值,与文本中出现的次数一样多。
  • @NeilMasters:g 修饰符在 PHP 中不存在。
  • 您的权利。今天我的脑子很糊:)
  • 我很好奇makeArrayOfValuesToReplace()getNewValueFor()的内容。可以发一下这两个函数吗?

标签: php regex arrays foreach


【解决方案1】:

只使用 str_replace(mixed $search , mixed $replace , mixed $subject) 怎么样?

您可以有一个搜索字符串数组,这些字符串将被替换数组中的相应项目替换,正如 PHP 手册所说:

如果您不需要花哨的替换规则(如正则表达式),则应始终使用此函数而不是 preg_replace()。

也只需关闭文件并以模式“w”重新打开它。文件将被截断为 0 长度

添加编辑

$fileContents = file_get_contents("theFile");
$search = array('apples', 'oranges');
$replace = array('pears', 'lemons');
$newContents = str_replace($search, $replace, $fileContents);
$handle = fopen("theFile","w");
fwrite($handle, $newContents);
fclose($handle);

就是这样,您的文件已将所有旧字符串替换为新字符串。

【讨论】:

  • 不确定我是否听懂了您在此处所说的内容。我花了很长时间才按照我想要的方式获得数组......并将这个函数降到最低...... str_replace 不是问题......问题是我必须首先更改所有出现的字符串....但是以某种方式将其保留为循环外我可以用来写入文件的值。这将是(我认为)解析 100 个文件的最快方法,其中一些文件需要更改 100 个值....
  • 你只有 2 个数组 $search = array('apples', 'oranges'); $replace = array('梨', '柠檬');。然后 $newFileContents = str_replace($search, $replace, $holdcontents);然后所有出现的“苹果”都将更改为梨,所有“橙子”将更改为“柠檬”
  • 我不认为你在这里遇到了问题。我在这里尝试做的算法是:打开文件,打开文件时将每个数组值“this”替换为“this”,以某种方式将整个结果保存在一个值中,关闭文件打开时,然后写入该文件的值替换了最初的文件。编辑:为了安全,必须有一个 preg_replace 我只替换这些值。也许一个词以苹果开头......就像苹果酱......我不想替换它......只是任何出现的苹果。只是。除了你为什么坚持 str_replace :) ?那工作正常...
  • 刚刚添加了代码编辑。文件中的所有苹果都将替换为梨,所有橙子都将替换为柠檬。您显然会设置自己的搜索和替换数组...
  • str_replace 比 preg_replace 快很多倍,这就是我建议的原因。如果速度不是问题,那么使用 preg_replace 你是对的,它确实解决了单词边界问题。
【解决方案2】:

问题没有解决办法。 file_get_contents 和 file_put_contents 根本不能那样工作。 感谢大家对这个问题的关注。

【讨论】:

    猜你喜欢
    • 2019-03-21
    • 2011-06-26
    • 1970-01-01
    • 2018-05-07
    • 1970-01-01
    • 2017-07-14
    • 2014-02-01
    • 2014-02-05
    • 2011-01-10
    相关资源
    最近更新 更多