Трудности с использованием переменных при вызове Ruby gsub для замены блока

#ruby #regex

#ruby #регулярное выражение

Вопрос:

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

 [varA][varB]_begin[varC]
content line 1
content line 2
...
[varA][varB]_end[varC]
  

И я хочу заменить все, включая первый varA и последний varC.

Я собрал скелет регулярного выражения, чтобы соответствовать этому. Итак, предположим, что varA было «<%», а varB было «block», а varC было «%>», регулярное выражение должно было бы быть:

 /<%block_beg%>(.*)<%block_end%>/m/
  

Я подтвердил, что этот шаблон должен работать (через rubyxp)

Но, конечно, это не так просто, потому что значения, которые мы использовали для varA, varB и varC в предыдущих примерах, должны предоставляться динамически.

Учитывая то, что я понимаю о Ruby gsub(), по моей оценке, должно сработать следующее:

  gsub(/#{@varA}#{@varB}_beg#{@varC}(.*)#{@varA}#{@varB}_end#{@varC}/m, old_str)
  

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

Примечание к сообщению 1: @ ‘s связаны с тем фактом, что переменные являются свойствами класса.

Примечание к сообщению 2: Я исправил несколько вещей, и это все еще не работает. Теперь у меня есть:

  @content.gsub(/#{Regexp.escape(@varA)}#{Regexp.escape(@varB)}_beg#{Regexp.escape(@varC)}(.*)#{Regexp.escape(@varA)}#{Regexp.escape(varB)}_end#{Regexp.escape(@varC)}/m)
  

Кто-нибудь знает, почему это не работает?

Комментарии:

1. Технически говоря, в конкретном экземпляре, над которым я работаю, все они должны иметь @ ‘s, потому что они являются свойствами класса.

2. Я бы рекомендовал провести рефакторинг и заменить ваши переменные, которые вы хотите интерполировать с помощью хэша. Затем просто выполните итерацию по хэшу и замените каждый ключ значением.

3. Сначала создайте свое регулярное выражение и присвоите его переменной, а затем p myregexp . Посмотрите, какое регулярное выражение вы на самом деле используете. Я предполагаю, что ваши переменные экземпляра являются nil , #to_s у которых является пустой строкой, и поэтому ваше регулярное выражение является /_beg(.*)_end/m .

4. Второй аргумент отсутствует в вашем gsub пост-примечании 2.

Ответ №1:

Ваше gsub выглядит не совсем правильно. Вот как я бы это сделал:

 old_str.gsub(/#{varA}#{varB}_begin#{varC}(.*)#{varA}#{varB}_end#{varC}/m)
  

Кроме того, если ваши переменные являются строками, вы, вероятно, захотите сначала вызвать Regexp.escape их, чтобы они были сопоставлены как литеральные строки, а не как директивы regexp.

Комментарии:

1. Смотрите изменения к моему исходному сообщению (примечания к сообщению 1 и 2) .. все еще возникают проблемы