0

正規表現が一致しすぎるという問題があります。できるだけ貪欲にならないように心がけました。私のREは:

 define host( |\t)*{(.*\n)*?( |\t)*host_name( |\t)*HOST_B(.*\n)*?( |\t)*}

意味

「ホストの定義」の後にスペースまたはタブが続き、その後に「{」が続きます。任意の数のスペースまたはタブの後に「host_name」が続き、その後に任意の数のスペースまたはタブが続き、その後に「HOST_B」が続くまでの任意のテキストおよび改行。スペースまたはタブの後に「}」が続くまでのテキストと改行

私のテキストは

define host{
    field stuff
        }

define timeperiod{
        sunday          00:00-03:00,07:00-24:00
        }

define stuff{
        hostgroup_name                  things
        service_description             load
        dependent_service_description   cpu_util
        execution_failure_criteria      n
        notification_failure_criteria   w,u,c
        }

define host{
        use                     things
        host_name               HOST_A
        0alias                  stuff 
       }

define host{
        use                     things
        host_name               HOST_B
        alias                   ughj
        address                 1.6.7.6
       }

define host{
        use                     things
        host_name               HOST_C
       }

一致は、最初の定義からhost_bの終了ブラケットに向かっています。host_cのグループを取得していません(host_cを取得するべきではありません)が、ホストbのグループのみを取得し、全体を取得することはできません。

何か助けはありますか?私の正規表現はさびています。http://regexpal.com/でテストできます

4

3 に答える 3

1

私はそれをテストしていませんが、[^{]*で。*を削除する必要があると思います。このようにして、正規表現は次の「{」を食べません。

これは私には奇妙に見えます:(.*\n)*? ドットを見てください:このフラグを設定すると、ドットは改行を食べます。

于 2013-02-14T16:19:29.383 に答える
1

あなたが求めていたものとは少し異なりますが、あなたは結果が好きかもしれないと思います。これにより、すべての構造が解析され、Python辞書に読み込まれます。そこから、操作は本当に素晴らしく、簡単なはずです。

mDefHost = re.findall(r"\define host{(.*?)\}",a,re.S)
mInHost  = re.compile("(\S+)\s+(\S+)")
hostDefs = []

for item in mDefHost:
    hostDefs.append( dict(mInHost.findall(item)) )

ex出力

>>> m = re.findall(r"define host\{(.*?)\}",a,re.S)
>>> m
['\n        use                     things\n        host_name               HOST_B\n            alias                   ughj\n        address                 1.6.7.6\n       ']
>>> item = m[0]
>>> item
'\n        use                     things\n        host_name               HOST_B\n            alias                   ughj\n        address                 1.6.7.6\n       '
>>> results = re.findall("(\S+)\s+(\S+)",item)
>>> results
[('use', 'things'), ('host_name', 'HOST_B'), ('alias', 'ughj'), ('address', '1.6.7.6')]
>>> dict(results)
{'alias': 'ughj', 'use': 'things', 'host_name': 'HOST_B', 'address': '1.6.7.6'}
于 2013-02-14T17:00:58.697 に答える
1

問題は、正規表現を使用して文字列全体を検索しているが、文字列全体の先頭と見分けがつかない方法で始まる部分文字列を見つけようとしていることです。貪欲でないマッチングを使用して、開始点をできるだけ遅くすることはできません。欲張りでない修飾子は、Regexエンジンが一致するものを見つけるためにどれだけ先を見るかにのみ影響します。

必要なのは、define hostとの間に閉じ括弧がないことを確認することですHOST_B。これを試してください(テストされていません):

define host\s*{[^}]HOST_B.*?}

.(改行を一致させるためにフラグを使用していることを確認してください。)

于 2013-02-14T17:18:41.867 に答える