2011-04-19 25 views
7

我在Ruby中有一個正則表達式,它在多行模式下無法正常工作。如何在Ruby中修復這個多行正則表達式?

我試圖將Markdown文本轉換爲Redmine中使用的Textile-eque標記。問題出在我的正則表達式轉換代碼塊。它應該找到任何帶有4個空格或製表符的行,然後將它們包裝在標記中。

markdownText = '# header 

some text that precedes code 

    var foo = 9; 
    var fn = function() {} 

    fn(); 

some post text' 

puts markdownText.gsub!(/(^(?:\s{4}|\t).*?$)+/m,"<pre>\n\\1\n</pre>") 

預期的結果:

# header 

some text that precedes code 

<pre> 
    var foo = 9; 
    var fn = function() {} 

    fn(); 
</pre> 

some post text 

的問題是,閉合預標籤在所述文檔的末尾,而不是後打印 「FN();」。我想下面的表達式的一些變化,但它不匹配:

gsub!(/(^(?:\s{4}|\t).*?$)+^(\S)/m, "<pre>\n\\1\n</pre>\\2") 

如何獲得正則表達式匹配只是縮進代碼塊?你可以在Rubular here上測試這個正則表達式。

+1

爲什麼不包括換行符在你的正則表達式:'((?:?\ S {4} | \ t)* \ N)+' – 2011-04-19 16:51:10

+0

除了XHTML自足[正則表達式匹配開放標籤的可能重複標籤](http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags) – 2011-04-20 23:09:36

+0

@Mladen Jablanovic我無法讓你的例子使用這段代碼工作: '放置markdownText.gsub!(/((?:\ s {4} | \ t)。*?\ n)+ /,「

\n\\1\n
」)'。 '\ n'與'$'有什麼不同? – DonovanChan 2011-04-21 15:45:22

回答

12

首先需要注意的是,'m'在Ruby中的多行模式相當於's'其他語言的單行模式。換一種說法; Ruby中的'm'模式表示:「點全部匹配」

此正則表達式會做匹配降價般的代碼段的一個不錯的工作:

re =/# Match a MARKDOWN CODE section. 
    (\r?\n)    # $1: CODE must be preceded by blank line 
    (     # $2: CODE contents 
     (?:    # Group for multiple lines of code. 
     (?:\r?\n)+  # Each line preceded by a newline, 
     (?:[ ]{4}|\t).* # and begins with four spaces or tab. 
    )+     # One or more CODE lines 
     \r?\n    # CODE folowed by blank line. 
    )     # End $2: CODE contents 
    (?=\r?\n)   # CODE folowed by blank line. 
    /x 
result = subject.gsub(re, '\1<pre>\2</pre>') 

這需要一個空行之前和代碼段後,允許代碼段本身的空行。它允許\r\n\n線路終端。請注意,這不會在每行之前去掉前四個空格(或製表符)。這樣做需要更多的代碼複雜性。 (我不是一個紅寶石的傢伙,所以不能幫助那個。)

我建議看着降價源本身,看看它是如何真正做到。

+0

感謝ridgerunner的詳細評論。我認爲你是迄今爲止唯一的答案,實際上我的規格開箱即用。 – DonovanChan 2011-04-20 03:14:13

0

/^(\s{4}|\t)+.+\;\n$/m

工作好一點,仍然拿起我們不想要一個換行符。 here它是在紅色的。

+0

看到ridgerunner的帖子後,我發佈了這個,絕對是一個更好的答案。 – 2011-04-19 17:02:52

0

Here的另一個捕獲在一個單一的塊

((?:^(?: {4}|\t)[^\n]*$\n?)+) 
0

這是爲我工作與樣品輸入所有縮進的行。

markdownText.gsub(/\n?((\s{4}.+)+)/, "\n<pre>#{$1}\n</pre>")