在这种情况下,我必须替换其中的某些字符串。我知道这些部分在哪里以及它们的外观(换句话说,我可以通过正则表达式将它们匹配),但不仅我不知道确切的内容,而且字符串中可能有相似的子字符串。 我要实现的是仅替换该偏移量处的特定事件,而其余部分保持不变。
一个例子:
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)
不能替换)
我知道我应该发布有关该问题的尝试,但半个小时以来我一直在盯着代码,但从中没发现任何想法(在放弃并提出要求之前,我一直盯着代码待了很长时间。过去,但今天我有点着急),但是我有一种解决方案比我想象的简单的感觉。我唯一意识到的是我应该以相反的顺序替换字符串,这样我就不会修改位置
答案 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)
相匹配。