Подберите и замените слово, отсутствующее в кавычках (строка содержит экранированные кавычки) - PullRequest
0 голосов
/ 20 января 2019

Как я могу заменить все вхождения определенного слова из заданной строки другим, если слово не встречается в кавычках.Обратите внимание, что входная строка, скорее всего, будет содержать экранированные кавычки.Само слово не будет содержать кавычек.

[РЕДАКТИРОВАТЬ: оригинальная формулировка была - «Входная строка обязательно будет содержать экранированные кавычки».Позже я понял, что это не «определенно», а «скорее всего»].

Пример: замена FOO на BAR

Ввод: FOO "FOO" 'FOO' " 1 + FOO + 2 " ABCFOOXYZ " str1\"FOO\"str3'FOO'\'\'" ' str1\'FOOstr3"FOO"\"\"' \"FOO\"

Вывод: BAR "FOO" 'FOO' " 1 + FOO + 2 " ABCBARXYZ " str1\"FOO\"str3'FOO'\'\'" ' str1\'FOOstr3"FOO"\"\"' \"BAR\"

Обратите внимание, что последнее появление FOO находится не внутри кавычек, сами цитаты были экранированы.Следовательно, он заменяется на BAR.

Я ищу регулярное выражение в JavaScript.

уточнение - Входная строка будет содержать как одинарные, так и двойные кавычки, возможно, оба экранированы.Мы должны заменять слово только тогда, когда оно вообще не заключено в кавычки (ни с одинарными, ни с двойными кавычками).

РЕДАКТИРОВАТЬ:

Что я пытался: мне удалось получить все вхождения FOO, которые НЕ должны подвергаться замене (["']) (?: (? = (\?))\ 2.) *? \ 1 Вышеуказанное будет соответствовать всем приведенным строкам. Они должны быть исключены из замены.

Я не специалист по регулярным выражениям и не могу выйти за рамки этого, много пробовал.

1 Ответ

0 голосов
/ 20 января 2019

Вы можете сопоставить все между одинарными или двойными кавычками, используя группу захвата, класс символов и обратную ссылку (['"]), так что одна и та же начальная кавычка соответствует одной и той же закрывающей кавычке. Затем используйте чередование для захвата FOO во второй группе захвата.

Метод replace имеет функцию обратного вызова, в которой вы можете получить доступ к полному совпадению в качестве первого параметра и к группам захвата в качестве оставшихся параметров. Здесь вы можете проверить значение второй группы. Если это FOO, верните BAR.

Если это не так, вернуть полное совпадение.

(?:\s|^)(['"])(?:\1|.*?[^\\]\1)|(FOO)

Объяснение

  • (?:\s|^) Начало строки или пробела
  • (['"]) Совпадение ' или " в группе захвата
  • (?: Группа без захвата
    • \1 Ссылка на первую группу захвата
    • | или
    • .*?[^\\]\1 Соответствует любому символу, кроме символа новой строки, не являющегося жадным, с последующим без обратной косой черты и обратной ссылки на группу 1
  • ) Закрыть группу без захвата
  • | или
  • (FOO) Группа захвата 2, содержащая FOO

Regex demo

let pattern = /(?:\s|^)(['"])(?:\1|.*?[^\\]\1)|(FOO)/g;
let str = `FOO "FOO" 'FOO' "    1 + FOO + 2 " ABCFOOXYZ "  str1\\"FOO\\"str3'FOO'\\'\\'" '  str1\\'FOOstr3"FOO"\\"\\"' \\"FOO\\"`;
let res = str.replace(pattern, function(m, _, g2) {
  return g2 === "FOO" ? "BAR" : m;
});
console.log(res);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...