2011-01-30 8 views
4

ルビー(レールではない)を使用して、静的ファイルの特定のブロックを文字列で置き換える(追加しない)方法を見つけようとしています。例えば、static_file.htmlに私は、HTMLのコメントは、「開始」と「終了」の間のすべてを置き換えたい:2つのマーカーの間のファイル内の内容を置換する

<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/)のいずれかを調べるとよいでしょう。個人的には、私はHAMLを好きなHTMLの略語として好む。別のコンテンツをボイラープレートに挿入する必要がある場合は、検索/置換よりも優れたソリューションになります。 –

答えて

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 

我々が得る解析した後:コメントを見つけ、次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--> 
# >> 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 

それ:

# >> <!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

関連する問題