仅知道位置和结构时替换子字符串

时间:2018-10-14 19:28:41

标签: php replace substring

在这种情况下,我必须替换其中的某些字符串。我知道这些部分在哪里以及它们的外观(换句话说,我可以通过正则表达式将它们匹配),但不仅我不知道确切的内容,而且字符串中可能有相似的子字符串。 我要实现的是仅替换该偏移量处的特定事件,而其余部分保持不变。

一个例子:

Test String (this) Test (not this) Test Test (this) Test Test (and this) Test (this maybe)

我知道我必须替换与以下正则表达式匹配的字符串:\(.*?\),但前提是它们始于位置12, 62 and 78(换句话说,第一个(this)而不是第二个{ {1}}和(and this)。子字符串(this maybe)和第二个(not this)不能替换)

我知道我应该发布有关该问题的尝试,但半个小时以来我一直在盯着代码,但从中没发现任何想法(在放弃并提出要求之前,我一直盯着代码待了很长时间。过去,但今天我有点着急),但是我有一种解决方案比我想象的简单的感觉。我唯一意识到的是我应该以相反的顺序替换字符串,这样我就不会修改位置

1 个答案:

答案 0 :(得分:2)

这是我想出的:

$string = 'Test String (this) Test (not this) Test Test (this) Test Test (and this) Test (this maybe)';

$offsets = [12, 62, 78];
$replace = "REPLACED";

// work backwards so we don't have to keep track of changing offsets
rsort($offsets);

foreach ($offsets as $offset) {
    $string = preg_replace('/^(.{' . $offset . '})\([^\)]*\)/', '$1'.$replace, $string);
}

echo $string;
// Test String REPLACED Test (not this) Test Test (this) Test Test REPLACED Test REPLACED

请注意,未替换第二个(this),因为它不是从偏移量12、62或78开始。如果将其添加到$offsets数组中,则实际上是偏移量45。它也会被替换。

我在测试中注意到\(.*\)对于我解决它的方式来说太宽了,我改为将其更改为\([^\)*\)(本质上是:匹配方括号内的所有内容,只要它不是右括号即可本身)。我必须这样做,因为\(.*\)也与(this) Test (not this)相匹配。