7

正規表現を使用してテキストを必要に応じて変換しますが、HTML タグを保持したいと考えています。たとえば、「スタック オーバーフロー」を「スタック アンダーフロー」に置き換えたい場合、これは期待どおりに機能するはずstack <sometag>overflow</sometag>ですstack <sometag>underflow</sometag>

4

6 に答える 6

9

HTML を操作するときは、正規表現ではなく DOM ライブラリを使用します。

  • lxml: パーサー、ドキュメント、および HTML シリアライザー。また、解析には BeautifulSoup と html5lib を使用できます。
  • BeautifulSoup: パーサー、ドキュメント、および HTML シリアライザー。
  • html5lib: パーサー。シリアライザがあります。
  • ElementTree: ドキュメント オブジェクト、および XML シリアライザー
  • cElementTree: C 拡張として実装されたドキュメント オブジェクト。
  • HTMLParser: パーサー。
  • Genshi: パーサー、ドキュメント、および HTML シリアライザーが含まれています。
  • xml.dom.minidom: 標準ライブラリに組み込まれたドキュメント モデルで、html5lib が解析できます。

http://blog.ianbicking.org/2008/03/30/python-html-parser-performance/から盗まれました。

これらのうち、lxml、html5lib、および BeautifulSoup をお勧めします。

于 2009-12-06T17:46:11.957 に答える
3

任意の置換を明確に行うことはできないことに注意してください。次の例を検討してください。

1)

HTML:

A<tag>B</tag>

パターン -> 置換:

AB -> AXB

考えられる結果:

AX<tag>B</tag>
A<tag>XB</tag>

2)

HTML:

A<tag>A</tag>A

パターン -> 置換:

A+ -> WXYZ

考えられる結果:

W<tag />XYZ
W<tag>X</tag>YZ
W<tag>XY</tag>Z
W<tag>XYZ</tag>
WX<tag />YZ
WX<tag>Y</tag>Z
WX<tag>YZ</tag>
WXY<tag />Z
WXY<tag>Z</tag>
WXYZ

ケースでどのようなアルゴリズムが機能するかは、可能な検索パターンの性質と、あいまいさを処理するための望ましいルールに大きく依存します。

于 2009-12-06T21:14:12.240 に答える
3

Beautiful SoupまたはHTMLParserがあなたの答えです。

于 2009-12-06T17:46:16.043 に答える
1

lxmlまたはによって提供されるようなhtmlパーサーを使用しBeautifulSoupます。もう1つのオプションは、XSLT変換(JythonのXSLT)を使用することです。

于 2009-12-06T17:56:00.223 に答える
0

これまでに投稿された DOM / HTML パーサー ライブラリの推奨事項は、指定された例の特定の問題に対処しているとは思いません。それらの間にタグがあるかどうかに関係なく、レンダリングされたドキュメントで が先行する場合にのみ にoverflow置き換える必要があります。ただし、このようなライブラリはソリューションに必要な部分です。underflowstack

タグが単語の途中に出現しないと仮定すると、1 つの解決策は次のようになります。

  1. DOM を処理し、すべてのテキスト ノードをトークン化し、各トークン (単語など) の先頭に一意の識別子を挿入します。
  2. ドキュメントをプレーンテキストとしてレンダリングする
  3. プレーンテキストを検索し、グループを使用して各トークンの先頭にある一意の識別子を照合、保持、およびマークする正規表現で置き換えます
  4. プレーンテキストからマークされた一意の識別子を持つすべてのトークンを抽出します
  5. 一意の識別子を削除し、マークされた一意の識別子に一致するトークンを対応する変更されたトークンに置き換えることにより、DOM を処理します。
  6. 処理された DOM を HTML にレンダリングする

例:

1. HTML DOM では、

stack <sometag>overflow</sometag>

DOMになる

#1;stack <sometag>#2;overflow</sometag>

そして 2. ではプレーンテキストが生成されます:

#1;stack #2;overflow

3. で必要な正規表現は で#(\d+);stack\s+#(\d+);overflow\bあり、代わりに#\1;stack %\2;underflow. 最初の単語は変更されていないため、2 番目の単語のみが一意の識別子で に変更#されてマークされることに注意してください。%

4. では、 を に変更してマークされているため、結果のプレーン テキストから番号付けされた一意の識別子を持つ単語が抽出されunderflowます。2#%

5. では、#(\d+);抽出された単語の中から番号を調べながら、DOM のテキスト ノードからすべての識別子が削除されます。番号1が見つからないため#1;stack、単純に に置き換えられますstack。番号2は変更された単語underflowで見つかったので、#2;overflowに置き換えられunderflowます。

最後に 6. で、DOM がレンダリングされて HTML ドキュメントに戻されます。

于 2009-12-06T20:52:46.083 に答える
-1

試してみる楽しいもの。それはちょっとうまくいきます。このスクリプトをテキストエリアに添付して「翻訳」させると、友達は気に入ってくれます。本当に何にでも使えそうです。うーん。コードを使用する場合は、コードを数回確認してください。動作しますが、これはすべて初めてです。PHPの勉強を始めて2、3週間経ったと思います。


<?php

$html = ('<div style="border: groove 2px;"><p>Dear so and so, after reviewing your application I. . .</p><p>More of the same...</p><p>sincerely,</p><p>Important Dude</p></div>');

$oldWords = array('important', 'sincerely');

$newWords = array('arrogant', 'ya sure');

// function for oldWords
function regex_oldWords_word_list(&$item1, $key)
{

    $item1 = "/>([^<>]+)?\b$item1(tionally|istic|tion|ance|ence|less|ally|able|ness|ing|ity|ful|ant|est|ist|ic|al|ed|er|et|ly|y|s|d|'s|'d|'ve|'ll)?\b([^<>]+)?/";

}

// function for newWords
function format_newWords_results(&$item1, $key)
{

    $item1 = ">$1<span style=\"color: red;\"><em> $item1$2</em></span>$3";

}

// apply regex to oldWords
array_walk($oldWords, 'regex_oldWords_word_list');

// apply formatting to newWords
array_walk($newWords, 'format_newWords_results');

//HTML is not always as perfect as we want it
$poo = array('/  /', '/>([a-zA-Z\']+)/', '/’/', '/;([a-zA-Z\']+)/', '/"([a-zA-Z\']+)/', '/([a-zA-Z\']+)</', '/\.\.+/', '/\. \.+/');

$unpoo = array(' ', '> $1', '\'', ';  $1', '"  $1', '$1  <', '. crap taco.', '. crap taco with cheese.');

//and maybe things will go back to normal sort of
$repoo = array('/>  /', '/;  /', '/"  /', '/  </');

$muck = array('> ', ';', '"',' <');

//before
echo ($html);

//I don't know what was happening on the free host but I had to keep stripping slashes
//This is where the work is done anyway.
$html = stripslashes(preg_replace($repoo , $muck , (ucwords(preg_replace($oldWords , $newWords , (preg_replace($poo , $unpoo , (stripslashes(strtolower(stripslashes($html)))))))))));

//after
echo ('<hr/> ' . $html);

//now if only there were a way to keep it out of the area between
//<style>here</style> and <script>here</script> and tell it that english isn't math.

?>
于 2010-05-15T08:55:58.087 に答える