0

Hyperic HQ によって生成されたアラートからの情報を解析する正規表現を作成しようとしています。アラートは、次のような件名の電子メールとして届きます。

"[HQ] !!! - Alert: My Demo Website Alert Resource: demo.myserver.net Apache Web Server State: fixed"

非常に長い話を短くまとめると、存在しない可能性があるホスト名に関係なく、「Apache Web サーバー」の部分を一貫して取得できる必要があります。ただし、ホスト名が常に「myserver.net」で終わることは知っています。

私が持っている正規表現は次のとおりです。

/Resource:\s.*(?<=mydomain.net)?\s(.*)\s(?=State)/

"Resource:"私は、これが と の間の 0 個以上の文字に一致し"State:"、オプションでホスト名に続く (ただし含まれていない)ことを期待していました。

残念ながら、返されるのは"Server"、つまり、一致させたいビットの最後の単語です。これは、ホスト名が文字列に含まれているかどうかに関係なく発生します。

誰でも助けることができますか?

編集:以下のChadが提供するソリューション

/Resource:\s(?:.*.myserver.net)?(.*)\sState/ 
4

3 に答える 3

3

これは、ルックアラウンドへの時期尚早の頼りと私が呼んでいるアンチパターンの例です。探している文字列の前後に があり、正規表現にはfoobar読みと先読みと呼ばれるものがあることがわかっているので、それを使用する必要があることは明らかです。

(?<=foo).*(?=bar)

明らかなことに注意してください。正規表現について直感的に理解できるものはほとんどありません。先読みはかなり遅れて正規表現に追加され、後読みはさらに遅れて追加されたことを思い出してください。しかし、人々はこの種の問題を解決するずっと前からこの種の問題を解決していました。彼らはキャプチャ グループを使用してそれを行いましたが、ほとんどの場合、これが依然として最適なオプションです。

foo(.*)bar

正規表現にも完全なエラーがあります:後読みの?量指定子:

(?<=mydomain.net)?

EditPadPro の検索ボックスは、PHP と同様にエラーとしてフラグを立てます。Java と .NET にはありませんが、そうすべきだと思います。\b*または^+またはよりも意味がありません${3,7}。これらはすべてゼロ幅のアサーションであり、何にも一致しないことを意味します。そのため、量指定子を追加することで、同じ何回も何回も一致させようとします (これ$は改行には一致しないことを思い出してください。改行と前の文字のの位置だけです) )。

無限ループに陥る危険はありませんが、これは正規表現の作成者がタイプミスをしたか、何かを誤解したことを示す良い兆候です。?これは、やのように、量指定子が 0 回一致するものである場合に特に当てはまります*。それはアサーションをオプションにし、オプションのアサーションは無関係なアサーションです。あなたの正規表現で(?<=mydomain.net)?は、「現在の位置の前にあるmydomain.netか、そうでないかのどちらかです。どちらの方法でもかまいません」を意味します。

いずれにせよ、Chad はすでに機能する正規表現を考え出しています。なぜあなたがそうしなかったのかについて、いくつかの洞察を提供したかっただけです。もちろん、私のアンチパターンをフィールドテストします。;)

于 2010-02-17T03:03:43.817 に答える
2

これは私が書いたテストで動作するようです

/Resource:\s(?:.*myserver.net)?(?<PartIWant>.*)\s(?:State)/

正規表現エンジンが名前付きキャプチャ グループをサポートしている場合、名前付きキャプチャ グループ "PartIWant" に含まれます。

編集:これらの文字列の両方でこの正規表現をテストしました

[HQ] !!! - Alert: My Demo Website Alert Resource: demo.myserver.net Apache Web Server State: fixed
[HQ] !!! - Alert: My Demo Website Alert Resource: Apache Web Server State: fixed
于 2010-02-16T21:05:23.083 に答える
1

場合によっては、単純なことができます。好きな言語で、「myserver.net」を分割してから、最初の要素の「State:」を分割します。例えばPythonで

>>> s="""[HQ] !!! - Alert: My Demo Website Alert Resource: demo.myserver.net Apache Web Server State: fixed"""
>>> s.split("myserver.net")[-1].split("State:")[0]
' Apache Web Server '
于 2010-02-17T03:10:30.183 に答える