2017-02-05 3 views
2

Ich versuche, alle Blöcke zu finden, die type:"Data" darin enthält, und ersetzen Sie es dann mit dem Text, den ich möchte.
Ein Abtastwerteingang unten gegeben wird, eine oder mehr von diesen sein kann:Wie kann ich diese Regex direkt in C# bekommen?

layer { 
    name: "cifar" 
    type: "Data" 
    top: "data" 
    top: "label" 
    include { 
    phase: TRAIN 
    } 
    transform_param { 
    mean_file: "examples/cifar10/mean.binaryproto" 
    mirror: true 
    #crop_size: 20 
    } 

# this is a comment! 
    data_param { 
    source: "examples/cifar10/cifar10_train_lmdb" 
    batch_size: 100 
    backend: LMDB 
    } 
} 
layer { 
    name: "cifar" 
    type: "Data" 
    top: "data" 
    top: "label" 
    include { 
    phase: TEST 
    } 
    transform_param { 
    mean_file: "examples/cifar10/mean.binaryproto" 
    } 
    data_param { 
    source: "examples/cifar10/cifar10_test_lmdb" 
    batch_size: 25 
    backend: LMDB 
    } 
} 

ich kam mit dieser Regex up:

((layer)(*)((\n))*{((.*?)(\n)*)*(type)(*):(*)("Data")((.*?)(\n)*)*)(.*?)(\n)} 

Ich habe versucht, dies zu modellieren:

find and select a block starting with layer, 
there can be any number of space characters but after it 
there should be a { character, 
then there can be anything(for making it easier), and then 
there should be a type followed by any number of spaces, then followed by "Data" 
then anything can be there, until it is faced with a } character 

Aber klar das funktioniert nicht richtig. Wenn ich den Typen in jedem dieser Schicht Blöcke zu ändern, wird nichts erkannt !, nicht einmal die Schicht, die das type : "Data"

+2

@Steve: Es ist nicht. Die Schlüssel (und einige Werte) werden nicht zitiert, und es gibt keine Kommas, plus '#' könnte für einen Kommentar verwendet werden. – Ryan

+0

In diesem Beispiel erscheint 'type' nur in' layers' und immer nach 'name' und vorangestelltem' top'. Wenn dies immer der Fall ist, können Sie Ihre Regex erheblich vereinfachen. Welche Datenstruktur hat dieses Modell sonst? Verfügt sie über einen Tokenizer/Parser/AST, mit dem Sie die Daten zuverlässiger lesen können? Oder können Sie es zuerst in JSON/XML konvertieren? – Orphid

+0

Was kennzeichnet die Blöcke, die Sie nicht abgleichen möchten - enthalten sie konsistent etwas, an dem Sie z. 'type:" Foo "' und dann schließt du alle diese Blöcke aus, die nur mit den anderen übrig bleiben, die dann diejenigen mit 'type:" Data "' sind? –

Antwort

1

Basierend auf this post über .net mit regulären Ausdrücken zu tun hat Klammer passend Sie die Regex präsentierten anpassen können:

\((?>\((?<c>)|[^()]+|\)(?<-c>))*(?(c)(?!))\)

Es sieht für Sätze von ( und ) passend und Sie können einfach diejenigen tauschen für { und } (nichts, was sie in dieser Regex entkommen sind).

Dann können Sie das layer\s* Bit voranstellen.

Für die Funktion blockiert auszuschließen, in denen type <>"Data" ich eine negative Vorschau für alle anderen type Keywords in Ihrer Probe in der Pastebin hinzugefügt haben. Leider hat das Hinzufügen eines postiven Lookaheads für type: "Data" einfach nicht funktioniert und ich denke, wenn das der Fall wäre, wäre das deine robusteste Lösung.

Hoffentlich haben Sie eine endliche Liste von type Werte und Sie können diese für eine praktische Lösung erweitern:

layer\s*{(?>{(?<c>)|[^{}](?!type: "Accuracy"|type: "Convolution"|type: "Dropout"|type: "InnerProduct"|type: "LRN"|type: "Pooling"|type: "ReLU"|type: "SoftmaxWithLoss")+|}(?<-c>))*(?(c)(?!))}

Der Schlüssel Bit arbeiten mit in der ursprünglichen Regex ist die [^()]+, die zwischen den Spielen Inhalt Klammern, die von den anderen Komponenten der Regex abgeglichen werden. Ich habe das an [^{}]+ angepasst - sei 'alles andere als die Klammern' - und fügte dann die lange Klausel 'abgesehen von' hinzu, damit die Schlüsselwörter nicht übereinstimmen.

Verwandte Themen