2011-04-19 2 views
7

Ruby에서 여러 줄 모드에서 제대로 작동하지 않는 정규식이 있습니다.이 다중 행 정규 표현식을 Ruby에서 어떻게 수정합니까?

마크 다운 텍스트를 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>") 

의도 된 결과는 "FN();"

# header 

some text that precedes code 

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

    fn(); 
</pre> 

some post text 

문제가 폐쇄 사전 태그는 문서의 끝에 대신 후 인쇄되어있다. 나는 다음과 같은 표현의 몇 가지 변화를 시도했지만이 일치하지 않습니다

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

가 어떻게 정규 표현식 그냥 들여 쓰기 코드 블록을 일치합니까? Rubular here에서이 정규식을 테스트 할 수 있습니다.

+1

이 왜 정규식에 줄 바꿈을 포함하지 :'((:?.? \의 {4} | \ t) * \ n)를 XHTML 자체에 포함 제외 [정규식 일치 열린 태그 +' –

+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' 모드는 의미 : "점 모두 일치"입니다. 이 정규식은 인하와 같은 코드 섹션을 일치 꽤 좋은 일을 할 것입니다

는 :

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

자세한 설명을 주셔서 감사합니다 ridgerunner. 지금까지 내 스펙에 실제로 적용된 유일한 대답은 내 생각이었습니다. – DonovanChan

0

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

은 여전히 ​​조금 더 잘 작동 우리가 원하는하지 않는 줄 바꿈을 선택합니다. here 루블리입니다.

+0

내가 이것을 게시 한 후에 ridgerunner의 게시물을 보았습니다. 더 나은 대답이었습니다. –

0

Here의이 샘플 입력을 나를 위해 노력하고 단일 블록

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

의 모든 들여 쓰기 라인을 캡처 또 하나.

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