Я думаю, что нашел решение для проблемы на GitHub, но это связано с немного сложным RegEx в Ruby. (Я редко работал с Ruby и не назвал бы себя профессионалом в RegEx). Проблема в том, что когда у вас есть, скажем, 5 (все, что больше 3) открывающих обратных кавычек, затем парсер встречает 3 обратные кавычки, он автоматически закроет блок кода. В основном код выглядит следующим образом:
def escape_liquid_tags_in_codeblock(content)
# Экранировать блоки кода, кодовые фрагменты и встроенный код
content.gsub(/[[:space:]]*~{3}.*?~{3}|[[:space:]]*`{3}.*?`{3}|`{2}.+?`{2}|`{1}.+?`{1}/m) do |codeblock|
codeblock.gsub!("{% endraw %}", "{----% endraw %----}")
codeblock.gsub!("{% raw %}", "{----% raw %----}")
if codeblock.match?(/[[:space:]]*`{3}/)
"\n{% raw %}\n#{codeblock}\n{% endraw %}\n"
else
"{% raw %}#{codeblock}{% endraw %}"
end
end
end
Прежде всего, блок кода в Markdown может содержать по крайней мере 3 обратные кавычки (`) или тильды (~), а не обязательно ровно 3. Я верю, что знаю решение этой проблемы, но мне нужно узнать, возможно ли написать что-то вроде этого?
[[:space:]]*`{N}.*?`{N}
где N может быть любым числом, но, конечно, количество начальных и закрывающих кавычек должно быть равным.
Я также считаю, что условие if должно быть {3,}
, а не {3}
. Если кто-то может сказать мне, как иметь regex с N начальными обратными кавычками и N закрывающими обратными кавычками, это было бы здорово. Я также открыт для любых предложений о том, как подойти к этой проблеме.
Я пытался задать это ChatGPT, но он не дал мне правильный RegEx, если это вообще возможно.
Я не знаю Ruby regex, но это решение является корректным согласно https://regex101.com/
Во-первых, я согласен с вашим утверждением “по крайней мере”:
- Измените
{3}
на{3,}
, чтобы соответствовать по крайней мере 3 символам.
Далее, группы захвата также применяются здесь (в PCRE).
- Измените …
{3,}.*?{3,}
… на: …{(3,)}.*?{\1}
Это regex, который я тестирую на сайте, указанном выше:
[[:space:]]*~{3}.*?~{3}|[[:space:]]*`{(3,)}.*?`{\1}|`{2}.+?`{2}|`{1}.+?`{1}
Обратите внимание, что я изменил это только для варианта с обратными кавычками. Вам нужно сделать то же самое для тильды и изменить \1
на \2
соответственно. Согласно подсветке, это работает отлично. Посмотрите:
Это работает для PCRE (Perl, PHP), Javascript, Python и .NET; но не работает для Golang, Java 8 и Rust, которые не поддерживают группы захвата, помещенные в это место. Обратите внимание, что последние несоответствующие обратные кавычки не подсвечиваются.
Ответ
Ваша задача состоит в том, чтобы создать регулярное выражение Ruby для поиска блока кода, который начинается и заканчивается одинаковым количеством обратных кавычек (backticks). При этом можно использовать N количества обратных кавычек, где N больше или равно 3.
Вот как можно решить эту задачу, используя регулярные выражения Ruby.
Решение
Для того чтобы создать регулярное выражение, удовлетворяющее этим условиям, мы можем воспользоваться следующим подходом:
- Подходящая конструкция: Для поиска минимум трёх обратных кавычек, которые будут одинаковыми как в начале, так и в конце, мы используем конструкцию с захватывающей группой.
- Регулярное выражение: Вот окончательное выражение, которое вы можете использовать:
content.gsub(/([`~]{3,})\s*(.*?)\s*\1/m) do |codeblock|
codeblock.gsub!("{% endraw %}", "{----% endraw %----}")
codeblock.gsub!("{% raw %}", "{----% raw %----}")
"\n{% raw %}\n#{codeblock}\n{% endraw %}\n"
end
Объяснение регулярного выражения
([
~]{3,}): Эта часть ищет последовательность из не менее чем трёх символов (
или ~) и помещает её в захватывающую группу. Мы используем круглые скобки, чтобы зафиксировать эту последовательность для дальнейшего использования.\s*
: Эта часть ищет любое количество пробелов (включая ноль) между открывающей и закрывающей последовательностью.(.*?)
: Эта часть находит любое содержимое между открывающей и закрывающей последовательностями. Знак вопроса делает поиск «ленивым» (он пытается минимизировать количество совпадений).\1
: Здесь происходит проверка, чтобы закрывающая последовательность соответствовала той же самой последовательности, что и открывающая (что захвачено в первой группе).
Пример использования
Пример того, как можно использовать это регулярное выражение в методе:
def escape_liquid_tags_in_codeblock(content)
content.gsub(/([`~]{3,})\s*(.*?)\s*\1/m) do |codeblock|
codeblock.gsub!("{% endraw %}", "{----% endraw %----}")
codeblock.gsub!("{% raw %}", "{----% raw %----}")
"\n{% raw %}\n#{codeblock}\n{% endraw %}\n"
end
end
Заключение
Это регулярное выражение работает как для обратных кавычек, так и для тильд, так как вы имеете возможность добавлять их в выражение. Обратите внимание, что группы повторов также могут быть применены для каждого варианта (тильда и кавычки). Убедитесь, что вы правильно обрабатываете и другие типы кода в вашем методе. Надеюсь, это поможет вам разобраться с вашей задачей!