2009-07-25 6 views
0

HTML ブロックタグを含まないすべての隣接行を抽出する正規表現を探していますが、HTML インラインタグを含むことができます。例えば、私は次のテキストを持っている場合...HTMLブロックタグを含まない行を抽出する正規表現

bla bla bla bla 
bla <code>bla bla</code> bla 
bla bla bla bla 
<img src="" alt="" /> 
bla bla bla bla 
<div> bla bla bla 
bla bla bla 

...私は次の行を抽出したいと思います...

bla bla bla bla 
bla <code>bla bla</code> bla 
bla bla bla bla 
<img src="" alt="" /> 
bla bla bla bla 

は何をすることができ、この

はあります正規表現で?

更新:私はPHPを使用しており、これらのブロックタグの名前を含む変数もあります。 ブロックタグがオープンタグまたはクローズタグの場合は問題ありません。

$blockTags = "h1|h2|h3|h4|h5|h6|hr|ol|ul|li|pre|blockquote|p|table|tr|td|div"; 
+2

正規表現ですべてが可能です。 :) – cakeforcerberus

+4

@semirhage:ああ、私は今すぐコメントをdownvoteすることができますしたい。 – Sean

+0

Darth Eruのようなサウンドはユーモアのセンスがありません。 –

答えて

2

あなたのタスクには、HTMLタグのオープンとクローズを理解できるパーサーが必要です。これは、古典的な正規表現ではできないものです。

現代の正規表現はこのようなトリックを引き出すことができるかもしれませんが、あなたは世界がこれまで見たことのない紛れもなく読みにくい正規表現を構築しますが、あなたはおそらく全部を書き直すことになるでしょう。だからあなたのためにそれを行うための比較的単純なパーサーを書くと、他の誰かが後で理解しようと時間を費やすだろういくつかの正規表現を作ろうと時間を費やすことはありません。

ところで、正規表現の質問をする場合は、使用している言語を指定してください。彼らは、少しずつ異なった言語で動作します。

+0

はい、言語を指定します。しかし、タグがオープンタグかクローズタグかどうかは関係ありません。 – kiewic

+0

現代の正規表現がこのようなトリックを引き出すことができると言えば、後方参照を参照していますか?例えばサブ式を括弧でグループ化し、同じ式で一致する値を呼び出す無制限の後方参照を許可すると、実際にパターンがNP完全に一致します。 –

+1

彼は開閉タグについては気にしません。 HTMLのdivやその他のタグを含んでいない行が必要です。それがブロック要素の中か外かどうかは関係ありませんので、これには本当に「パーサー」は必要ありません。 –

1

さて、あなたは何ができるかあなたが最初

[^<>]* 

のようなものを持つ任意のHTMLタグを含めると、行が任意のHTMLインラインタグを持っているならば、チェックしない行をフィルタリングすることができ、次のとおりです。

<(/?)(code|img|...)(/?)> 

残りの部分にはブロックタグが含まれています。
これが十分に正確かどうかはわかりません。

1

これは、「唯一の正規表現」ではありませんが、それはあなたの入力文字列を考慮し、作業を行う必要がありますが$strである:

いくつかの単語で
$lines = explode(PHP_EOL, $str); 
$linesToKeep = array(); 

foreach ($lines as $line) { 
    if (!preg_match('#</?(' . $blockTags . ')>#', $line)) { 
     $linesToKeep[] = $line; 
    } 
} 

// Et voila ;-) 
$strOK = implode(PHP_EOL, $linesToKeep); 
var_dump($strOK); 

  • これは、文字列を爆発します(行ごとに保持または拒否したいので)行を操作します。行が<TAG>または</TAG>が、それは最終的に$linesToKeep配列
  • に置かれているが含まれていない場合
  • それはライン
  • で行をループし、出力に含まの文字列はその配列に何から構築されてい

しかし、もっと短い方法があるかもしれません...しかし、それは理解するのが簡単です。私は推測します(何か「正規表現の地獄」ないしは誰も維持できないものは^^)

編集:私はOPを再読していたので、私はnotic

$lines = explode(PHP_EOL, $str); 
$linesToKeep = array(); 
$i = 0; 
$numLines = count($lines); 

for ($i=0 ; $i<$numLines ; $i++) { 
    $line = $lines[$i]; 
    if (!preg_match('#</?(' . $blockTags . ')>#', $line)) { 
     $linesToKeep[] = $line; 
    } else { 
     if (preg_match('#<(' . $blockTags . ')>#', $line)) { 
      // Opening tag, skip next line too ? 
      $i++; 
     } 
    } 
} 

$strOK = implode(PHP_EOL, $linesToKeep); 
var_dump($strOK); 

そして、あなたがしたい場合:それは私のコードではありませんしながら、最後の行は、あなたはそれの後に開始タグとライン、および1つを除外したい場合は、ここで別の命題だ...、除外された編閉じるタグまで行をスキップするには、$i++を置く場所で行うことができますが、それは読んだり理解しづらいようになっています^^ (そして、HTMLの手書きを "解析する"というのは良い考えではないかもしれません。複雑なものにしたい^^)

+0

ねえ、あなたの最初の試みは良いですが、ELSEステートメントでBREAKするだけです。 preg_replace()呼び出しをシミュレートするために、私は$ linesToKeep []に参加し、変更を加え、残りの行と結合します。 – kiewic

関連する問題