Ruby: вложенные регулярные выражения и замена строк - PullRequest
0 голосов
/ 25 октября 2010

Я использую CodeRay для подсветки синтаксиса, но у меня проблемы с этим регулярным выражением. Текст будет выглядеть так:

<pre><code>:::ruby
def say_hello
  puts 'hello!'
end

Эта часть: :::ruby сообщит CodeRay, на каком языке следует интерпретировать блок кода (но он должен быть необязательным). Итак, вот что у меня есть:

def coderay(text)
  text.gsub(/\<pre\>\<code\>(.+?)\<\/code\>\<\/pre\>/m) do
    CodeRay.scan($2, $3).div()
  end
end

$2 содержит код, который я форматирую (включая строку, в которой указано, на каком языке его форматировать), но мне нужно извлечь эту первую строку, чтобы я мог передать ее в качестве второго параметра в scan() или передайте ему параметр по умолчанию, если эта языковая строка не была найдена. Как я могу это сделать?

1 Ответ

1 голос
/ 25 октября 2010

В Ruby 1.9 с использованием именованных групп:

default_lang=:ruby

def coderay(text)
  text.gsub(%r!<pre><code>(?::{3}(?<lang>\w+)\s+)?(?<code>.+?)
! M) делать, если $ ~ [: lang] .nil?lang = default_lang else lang = $ ~ [: lang] .intern end CodeRay.scan ($ ~ [: code], lang) .div () end end

default_lang также может бытьпеременная класса или объекта, а не локальная, в зависимости от контекста coderay.

То же самое, но с использованием встроенного выражения для обработки необязательного языка:

default_lang=:ruby

def coderay(text)
  text.gsub(%r!<pre><code>(?::{3}(?<lang>\w+)\s+)?(?<code>.+?)
! m) do CodeRay.scan($ ~ [: code], $ ~ [: lang] .nil?? default_lang: $ ~ [: lang] .intern) .div () end end

Второй вариант немногогрязнее, следовательно, вы можете захотеть избежать этого .

Оказывается, именованные группы в несоответствующей необязательной группе все еще учитываются в Ruby, поэтому обработка несопоставленных нумерованных групп ничем не отличаетсяиз непревзойденных именованных групп, в отличие от того, что я впервые подумал.Таким образом, вы можете заменить именованные групповые ссылки позиционными ссылками в приведенном выше коде, и это должно работать так же.

default_lang=:ruby

def coderay(text)
  text.gsub(%r!<pre><code>(?::{3}(?<lang>\w+)\s+)?(?<code>.+?)
! M) do CodeRay.scan ($ 2, $ 1.nil?? Default_lang: $ 1.intern) .div() end end def coderay (text) text.gsub (% r!
(?::{3}(?<lang>\w+)\s+)?(?<code>.+?)
! m) делать, если $ 1.nil?lang = default_lang else lang = $ 1.intern end CodeRay.scan ($ 2, lang) .div () end end
...