2012-03-26 4 views
0

HTMLソースでは、これらの3つの属性を正確に(それ以上、以下ではなく)FONTタグ内の任意の単純なテキストを任意の順序で抽出する必要があります:size = 5、color = "red"、face = "verdana"。htmlタグ内の属性をチェックするための正規表現

正規表現は、例えば、最後の4文字を除く以下の「randomtext」をすべて抽出する必要があります。

<font size=5 color="red" face="verdana">randomtext</font> 
<font size=5 face="verdana" color="red">randomtext</font> 
<font color="red" size=5 face="verdana">randomtext</font> 
<font color="red" face="verdana" size=5>randomtext</font> 
<font face="verdana" size=5 color="red">randomtext</font> 
<font face="verdana" color="red" size=5>randomtext</font> 
<font size=5 size=5 size=5>randomtext</font> 
<font face="verdana" color="red" size=5 foobar="random">randomtext</font> 
<font face="verdana" color="red" size=5 foobar="random=pippo">randomtext</font> 
<font face="verdana" color="red" size=5 garbagetext>randomtext</font> 

私は3ルック先読みを使用することにより、 "任意の順序で" 問題を解決:

<font(?=[^>]* size=5)(?=[^>]* color="red")(?=[^>]* face="verdana")[^>]*>([^<]+)</font> 

...以上のhtmlの柔軟性のために:

<\s*font(?=[^>]*\s+size\s*=\s*5)(?=[^>]*\scolor\s*=\s*["']red["'])(?=[^>]*\sface\s*=\s*["']verdana["'])[^>]*>\s*([^<]+?)\s*<\s*/font\s*> 

問題があることです最後の3つにも一致します。 これらの一致を除外するにはどうすればよいですか? (明らかに、一般的かつ合理的な短期間で/効率的な方法で、すべての可能な正の組み合わせを使用せずに、私の例でのみ機能するリテラルネガティブ表現を使用せずに)

+4

あなたはどの言語を使用していますか?このタスクは、適切なHTML解析ライブラリで処理するほうがずっと簡単です。 –

+0

Michael、言語に依存しない単一の正規表現で解決する必要があります。正規表現のフレーバーはPCREです。 – Imbuter

+0

この宿題はありますか? – huon

答えて

0

あなたはこれが難しいと認識していますか?別の可能性がある場合は、それを使用してください!

正規表現については、これを試してください、

  1. (?![^>]*(?<!color|size|face)=)が主張の背後にあるネストされた負の表情で否定先読みである:

    <font(?=[^>]* size=5)(?=[^>]* color="red")(?=[^>]* face="verdana")(?![^>]*(?<!color|size|face)=)(?:\s+[^>\s=]+=[^>\s=]+\s*)+>([^<]+)</font> 
    

    が、私が追加here on Regexr

    を参照してください/二つのことを変更しました前に色、大きさ、顔がないときは等号を許さない。

  2. 属性に一致する[^>]*(?:\s+[^>\s=]+=[^>\s=]+\s*)+に変更して、等号を含まない空白以外のシーケンスと一致するようにしました。また、正規表現は、仕事のためのツールではないと言う人によると

+0

私はこの正規表現が私の例の7番目と最後にも間違ってマッチすると思います。これまでのところ最良の解決策はBireiによるものです。さらにコンパクトな正規表現の解決法を探している(同じ属性を2回も含まない) – Imbuter

+0

Regexrのリンクを見たことがありますか?それは、あなたが望むようにすべてのあなたの例にマッチします。 – stema

+0

私はそれをRegexrでテストしたところ、 randomtextと一致することがわかりました。属性を繰り返すのは理にかなっていませんが、一致するものを除外することをお勧めします... – Imbuter

1

一つの方法、:

script.plのコンテンツ(内部正規表現とし、説明):

use warnings; 
use strict; 

while (<DATA>) { 
    printf qq[Text matched: %s\t (original string: %s)\n], $1, $& if 
    m/ 
     # At begin of line, '<' character plus optional space. 
     \A < \s* 
     # Literal 'font' word. 
     font 
     # Mandatory space. 
     \s+ 
     # Positive look-ahead for string 'size=5' 
     (?= .* size \s* = \s* 5 (?:\s+|>)) 
     # Positive look-ahead for string 'face="verdana"' 
     (?= .* face \s* = \s* "verdana" (?:\s+|>)) 
     # Positive look-ahead for string 'color="red"' 
     (?= .* color \s* = \s* "red" (?:\s+|>)) 
     # If last three look-ahead succeed, match them. 
     (?:size\s*=\s*5\s*|color\s*=\s*"red"\s*|face\s*=\s*"verdana"\s*){3} 
     # Literal '>' character. 
     > 
     # Text between tags. 
     ([^>]+) 
     # Close tag and match end of string. 
     <\/font> \Z 
    /x; 
} 

__DATA__ 
<font size=5 color="red" face="verdana">randomtext</font> 
<font size=5 face="verdana" color="red">randomtext</font> 
<font color="red" size=5 face="verdana">randomtext</font> 
<font color="red" face="verdana" size=5>randomtext</font> 
<font face="verdana" size=5 color="red">randomtext</font> 
<font face="verdana" color="red" size=5>randomtext</font> 
<font size=5 size=5 size=5>randomtext</font> 
<font face="verdana" color="red" size=5 foobar="random">randomtext</font> 
<font face="verdana" color="red" size=5 foobar="random=pippo">randomtext</font> 
<font face="verdana" color="red" size=5 garbagetext>randomtext</font> 

を実行し、それ以下のような:次のような結果と

perl script.pl 

Text matched: randomtext   (original string: <font size=5 color="red" face="verdana">randomtext</font>) 
Text matched: randomtext   (original string: <font size=5 face="verdana" color="red">randomtext</font>) 
Text matched: randomtext   (original string: <font color="red" size=5 face="verdana">randomtext</font>) 
Text matched: randomtext   (original string: <font color="red" face="verdana" size=5>randomtext</font>) 
Text matched: randomtext   (original string: <font face="verdana" size=5 color="red">randomtext</font>) 
Text matched: randomtext   (original string: <font face="verdana" color="red" size=5>randomtext</font>) 
+0

偉大なBirei、私は3つの属性を一度に繰り返す唯一の "欠陥"を持っている同じ解決策に到着しました。 – Imbuter

関連する問題