0

それらがどのように機能するかを理解するために、単純なレクサーを作成しようとしています。あらゆるタイプのOpeningHTMLタグをキャッチできる優れたPOSIX文字列を見つけようとしています。ほぼ機能するものを作成しましたが、メタタグなどのより複雑なタグでは失敗します。これまでのところ、これは私が持っているものです:

"<\\p{Alnum}+(\\p{Space}\\p{Alnum}+\\p{Space}*=\"*\\p{Space}*\\p{Alnum}+\"*)*\\p{Space}*>"

このPOSIX文字列は多くのタグをキャッチしますが、メタタグやDOCタグなどの一部を見逃しています。失敗したタグは次のとおりです。

<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

どんな助けでも大歓迎です。これはレクサーを作成するための最良の方法ではないかもしれませんが、これは正規表現がどのように機能するかを理解するのに役立つだけです。

4

2 に答える 2

3

引用符以外のもの

属性の値の場合、スキャンする正しい方法は、引用符ではないものと一致させることです。その部分の正規表現は次のようになります。

    \"[^\"]*\"

なぜあなたが持っているのかわかりません\"*; 引用符を繰り返すことはできません。可能な限り空白を許可したり、二重引用符に加えて一重引用符を受け入れたりするなど、他の問題があります(name='value'の代わりになりname="value"ます)。しかし、もっと大きな問題があるので、私は気を悪くしません。

字句解析プログラムの範囲を超えています

より重要な懸念は、レクサーに構文解析を詰め込みすぎていることです。レクサーの仕事は、文字のストリームをトークンのストリームに変換することです。トークンは、テキスト内の分割できない小さな単位です。開始タグ全体、要素名、属性、およびすべてを単一のトークンとして解析しようとはしません。

代わりに、タグの小さい部分(開き角かっこ、識別子、識別子、等号、文字列、閉じ角かっこ)をこじ開ける必要があります。レクサーにそれらの部分を認識させ、パーサーに任せて、これらのトークンがこの順序で要素タグを構成していることを確認します。

于 2010-12-09T04:23:24.837 に答える
1

あなたのPOSIX文字列"<\\p{Alnum}+(\\p{Space}\\p{Alnum}+\\p{Space}*=\"*\\p{Space}*\\p{Alnum}+\"*)*\\p{Space}*>"では、あなたは世話をhyphenしていないようですhttp-equiv

編集 非常に大雑把な正規表現は次のように書くことができます:

"</?\\w+((\\s+(\\w|\\w[\\w-]*\\w)(\\s*=\\s*(?:\".*?\"|'.*?'|[^'\">\\s]+))?)+\\s*|\\s*)/?>"

したがって、次のような入力の場合:

<html>
   <head>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
   </head>
   <body>
     <h4>Test Page</h4>
   </body>
</html>

出力は次のようになります。

<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <h4>
    </h4>
  </body>
</html>

上記の正規表現を処理命令として使用する場合は注意してください。CDATAノードと#Textノードは考慮されません。

これがお役に立てば幸いです。

于 2010-12-09T04:29:18.037 に答える