0

この質問の正規表現を見つけようとしています:

PHP解析xmlファイルエラー

負の先読みアサーションと後読みアサーションを使用して、次の文字列の「137b」と一致させようとしています。

<Rate Symbol="EURTRY">
    <Bid>2.29443</Bid>
    <Ask>2.29562</Ask>
    <High>2.29841</High>
    <Low>2.28999</Low>

 137b

 <Direction>1</Direction>
    <Last>23:29:11</Last>
</Rate>

誰かがこの正規表現が機能しない理由を指摘できますか?

(?<!(<\w+>))[a-zA-Z0-9_\.:]+(?!(</\w+>))

意図:「a-zA-Z0-9 _ .:」を含む文字列の前後にXMLタグがないため、「137b」と一致する必要がありますが、一致しません。

正規表現へのリンクは次のとおりです:http: //regexr.com?32rk4

一方、負のアサーションのない同じ正規表現は(<\w+>)[a-zA-Z0-9_\.:]+(</\w+>)、xmlタグ内のすべての文字列に正しく一致します。

http://regexr.com?32rk7

4

2 に答える 2

2

可変長の後読みは、ほとんどの正規表現フレーバーでサポートされていません。ここではそのように見えます。代わりにこれを試して、終了タグの代わりに開始タグが続くすべてのテキストに一致させます。

[a-zA-Z0-9_\.:]+(?=\s*<)(?!(</\w+>))

言うまでもなく、XML を構文解析するための正規表現のアプローチは脆く、これも例外ではありません。

于 2012-11-19T06:00:07.523 に答える
0

PHP では、これに後読みを使用することはできませんが、いずれにせよ、後読みはこの仕事に最適なツールではありません。(ほとんどありません。) 先読みだけで問題を解決できるはずです。ドキュメント構造について特定の仮定を立てることができれば、はるかに簡単になります。たとえば、囲んでいるノードの名前が常にRateであり、その子ノードが独自の子ノード (属性または要素) を持たないことを確認できますか? つまり、次のようなものは表示されません。

<Rate Symbol="EURUSD">
    <Bid>1.27554</Bid>
        <foo>bar</foo>
    <Ask foo="bar">1.27578</Ask>
</Rate>

その場合、肯定的な先読みを使用して、任意の数の完全な子ノードとその後に終了</Rate>タグを一致させることができます。

[a-zA-Z0-9_.:]++(?=\s*(?><(\w+)>[^<]*</\1>\s*)*+</Rate>)

説明する:

[a-zA-Z0-9_.:]++
(?=
  \s*
  (?>
    <(\w+)>       # match an opening tag and capture its name
    [^<]*         # consume the content
    </\1>         # match the closing tag
    \s*
  )*+           # do this zero or more times
  </Rate>       # confirm we're inside a <Rate> element
)

これは、元の質問で言及した他のジャンクに対処するために拡張することもできますが、正規表現は非常に醜くなるので、それだけの価値はないと思います。

于 2012-11-19T10:14:16.140 に答える