2011-04-19 7 views
7

मेरे पास रुबी में नियमित अभिव्यक्ति है जो मल्टीलाइन मोड में ठीक से काम नहीं कर रही है।रूबी में इस मल्टीलाइन नियमित अभिव्यक्ति को कैसे ठीक किया जाए?

मैं मार्कडाउन टेक्स्ट को Redmine में उपयोग किए जाने वाले वस्त्र-ईक मार्कअप में कनवर्ट करने का प्रयास कर रहा हूं। समस्या कोड ब्लॉक को बदलने के लिए मेरी नियमित अभिव्यक्ति में समस्या है। इसे 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") 

मैं कैसे नियमित अभिव्यक्ति बस दांतेदार कोड ब्लॉक मैच के लिए मिलता है? आप रूबलर here पर इस नियमित अभिव्यक्ति का परीक्षण कर सकते हैं।

+1

क्यों अपने regex में नई पंक्ति शामिल नहीं: '((:।? \ रों {4} | \ t) * \ N) +' –

+0

छोड़कर एक्सएचटीएमएल संयमी [रेगुलर एक्सप्रेशन से मेल खुला टैग की संभावित डुप्लिकेट टैग] (http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags) –

+0

@Mladen Jablanovic मुझे इस कोड का उपयोग करके काम करने के लिए आपका उदाहरण नहीं मिल सका: 'markdownText.gsub डालता है! (/ ((?: \ s {4} | \ t)। *? \ n) + /,"

\n\\1\n
")'। '\ N'' '' से अलग तरीके से व्यवहार कैसे करेगा? – DonovanChan

उत्तर

12

सबसे पहले, ध्यान दें कि 'm' रूबी में बहु-लाइन मोड 's' अन्य भाषाओं के सिंगल-लाइन मोड के बराबर है। दूसरे शब्दों में; रुबी में 'm' मोड का अर्थ है: "डॉट सभी से मेल खाता है"

इस regex एक markdown की तरह कोड अनुभाग मिलान की एक बहुत अच्छा काम करेगा:

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 लाइन समाप्ति के लिए अनुमति देता है। ध्यान दें कि यह प्रत्येक पंक्ति से पहले अग्रणी 4 रिक्त स्थान (या टैब) को पट्टी नहीं करता है। ऐसा करने के लिए और अधिक कोड जटिलता की आवश्यकता होगी। (मैं एक रूबी लड़का नहीं हूं इसलिए उसमें मदद नहीं कर सकता।)

मैं यह देखने के लिए मार्कडाउन स्रोत को देखने की सलाह दूंगा कि यह वास्तव में कैसे किया जा रहा है।

+0

विस्तृत टिप्पणियों के लिए धन्यवाद। मुझे लगता है कि अब तक आपका एकमात्र उत्तर था जो वास्तव में बॉक्स के बाहर मेरी चश्मा के लिए काम करता था। – DonovanChan

0

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

एक छोटे से बेहतर काम करता है, फिर भी एक नई पंक्ति है कि हम नहीं चाहते ऊपर उठाता है। here यह रूबलर पर है।

+0

ने इसे पोस्ट करने के बाद हाइपरगेनर की पोस्ट देखी, निश्चित रूप से एक बेहतर जवाब। –

0

Here की एक और एक है कि एक ही ब्लॉक

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

यह आपके नमूना इनपुट के साथ मेरे लिए काम कर रहा है में सभी दांतेदार लाइनों कैप्चर करता है।

markdownText.gsub(/\n?((\s{4}.+)+)/, "\n<pre>#{$1}\n</pre>") 
संबंधित मुद्दे