2011-01-30 6 views
4

레일이 아닌 루비를 사용하여 정적 파일의 특정 블록을 문자열로 바꾸는 (추가하지 않음) 방법을 알아 내려고했습니다. 예를 들어, static_file.html에서 나는 HTML 주석이 "시작"과 "끝"사이에 모든 것을 대체 할 :두 마커 사이의 파일 내용 바꾸기

<p>lorem ipsum blah blah ipsum</p> 

<!--start--> 
REPLACE MULTI-LINE 
CONTENT HERE... 
<!--end--> 

<p>other stuff still here...</p> 

answers here 중 일부는 특정 지점에 텍스트를 삽입하는 데 도움이됩니다,하지만 사이에 처리하지 않습니다 .

+0

템플릿 파일을 사용하여 HTML 콘텐츠를 생성하는 경우 ERB 또는 [HAML] (http://haml-lang.com/)을 검토 할 수 있습니다. 개인적으로, 나는 좋은 HTML 속기로서 HAML을 선호한다. 다른 콘텐츠를 상용구에 삽입해야하는 경우 검색/바꾸기보다 더 나은 솔루션이 될 것입니다. –

답변

4

다음은이를 처리하는 기능입니다. 그냥 그 HTML 주석 블록 사이에 대체하기 위해 그것을 파일 경로와 내용을 전달합니다 :만큼 귀하의 코멘트 블록은 항상 같은 포맷으로

을! < --start-- > 및 <->을 end-- ,이 작동합니다.

def replace(file_path, contents) 
    file = File.open(file_path, "r+") 
    html = "" 

    while(!file.eof?) 
     html += file.readline 
    end 

    file.close() 

    return html.gsub(/<!--start-->(.*)<!--end-->/im, contents) 
end 
+0

이렇게하면 시작 태그와 종료 태그가 바뀌지 만 대체 할 수있는 콘텐츠 주위를 쉽게 둘러 쌀 수 있습니다. 좋고 간단한 답변! – chronon

+0

파일 크기가 작은 경우 작동합니다. 로그 파일과 같이 크기가 크면 성능이나 서버 리소스 제약이 문제가됩니다. –

+0

문제 도메인은 HTML 파일입니다. 나는 정말로 공연이 문제가 될지 의심 스럽다. – Jordan

2

간단한 대답은 다음과 같습니다 그건 당신이 뭘 하려는지 충분히 강력한 있다면

str = "FOO\n\BAR\nblah \nblah BAZ\nBLOOP" 
str.gsub(/BAR.*BAZ/m,"SEE") 

잘 모르겠어요. 여기서 핵심은 여러 줄을 나타내는 정규 표현식의 끝에있는 'm'입니다. 템플릿에 일부 값을 지정하는 경우이 gsub 대신 ERB 템플릿과 같은 것을 볼 수 있습니다. 또한 정규 표현식에서 벗어날 필요가있는 것에주의하십시오.

+0

"REPLACE CONTENT ..."가 동적으로 생성/변경되므로 정규식을 사용하여 대체 할 내용을 알지 못합니다. – chronon

+0

이 정규식을 동적으로 만들 수 있습니다. r = Regexp.new "foo. * bar", Regexp :: MULTILINE – shawn42

1

이 파서 사용하여 작업을 수행하는 방법의 간단한 예입니다 : 우리를 분석 한 후

require 'nokogiri' 

html = '<p>lorem ipsum blah blah ipsum</p> 

<!--start--> 
REPLACE MULTI-LINE 
CONTENT HERE... 
<!--end--> 

<p>other stuff still here...</p>' 

doc = Nokogiri.HTML(html) 
puts doc.to_html 

얻을 :

# >> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"> 
# >> <html><body> 
# >> <p>lorem ipsum blah blah ipsum</p> 
# >> 
# >> <!--start--> 
# >> REPLACE MULTI-LINE 
# >> CONTENT HERE... 
# >> <!--end--> 
# >> 
# >> <p>other stuff still here...</p> 
# >> </body></html> 

doc.at('//comment()/following-sibling::text()').content = "\nhello world!\n" 
puts doc.to_html 

, 주석을 찾아 다음 text() 노드에 스테핑 교체 한 후 그것 :

# >> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"> 
# >> <html><body> 
# >> <p>lorem ipsum blah blah ipsum</p> 
# >> 
# >> <!--start--> 
# >> hello world! 
# >> <!--end--> 
# >> 
# >> <p>other stuff still here...</p> 
# >> </body></html> 

당신의 HTML은 언제나 단순하고 단순한 검색 패턴을 위반하는 문자열을 가질 가능성이있는 경우 검색/바꾸기를 수행 할 수 있습니다.

주변을 살펴보면 간단한 HTML 조작에 대해 파서를 사용해야한다는 것을 알 수 있습니다. 왜냐하면 문서의 실제 구조를 다루기 때문입니다. 따라서 문서가 변경되면 파서가 혼동되지 않을 가능성이 높아집니다.

+0

이 솔루션에서는 모든 주석을 대체하고 질문 상태와 같은 특정 구조를 대상으로하지 않는다고 가정합니다. 텍스트가 HTML 일 뿐이므로 파서를 가져 오는 것은 너무 과잉스러운 것처럼 보입니다. 여기서 전체 문서를 리플 로우하거나 다시 형식화하려고하지는 않습니다. – Jordan

+0

아니요, 내 해결책은 * FIRST *가 샘플과 일치한다고 가정합니다. 완전한 솔루션이 아니라 출발점으로 쓰여졌습니다. –

+0

예를 들어 주셔서 감사합니다.하지만 조금 더 복잡해지기를 바랍니다. 파서를 사용하는 방법에 대한 명확한 설명이 필요합니다. – chronon

관련 문제