Замените подстроку, когда знаете только положение и структуру - PullRequest
0 голосов
/ 14 октября 2018

У меня есть ситуация, когда у меня есть строка, из которой я должен заменить определенные детали.Я знаю, где находятся эти части и как они выглядят (другими словами, я могу сопоставить их через регулярное выражение), но не только я не знаю точного содержания, но и внутри строки могут быть похожие подстроки.Чего я хочу добиться, так это заменить только конкретное вхождение с этим смещением, оставив остальное нетронутым.

Пример:

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

Я знаю, что должен заменить строки, соответствующие этому регулярному выражению: \(.*?\) но только если они начинаются в позициях 12, 62 and 78 (другими словами, первая (this), но не вторая, (and this) и (this maybe). Подстроки (not this) и вторая (this) не должныбыть замененным)

Я знаю, что я должен публиковать свои попытки решить проблему, но я смотрю на код с получаса, и никакой идеи из него не вышло (я смотрел на код в течение более длительного временипрежде чем сдаться и спросить в прошлом, но сегодня я немного спешу) но у меня такое чувство, что решение проще, чем я думаю.Единственное, что я понял, это то, что я должен заменить строки в обратном порядке, чтобы не изменять позиции

1 Ответ

0 голосов
/ 14 октября 2018

Вот что я придумал:

$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. Этот на самом деле со смещением45, если вы добавите его в массив $offsets, он также будет заменен.

Я заметил в своих тестах, что \(.*\) слишком широк для того, как я его решил, и я изменил его на \([^\)*\) вместо этого (по существу: сопоставить что-либо в скобках, если это не закрывающая скобка).Я должен был сделать это, потому что \(.*\) также соответствует (this) Test (not this).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...