如何在c#中正确使用此正则表达式?

时间:2017-02-05 09:31:05

标签: c# regex

我正在尝试匹配其中包含type:"Data"的所有块,然后将其替换为我想要的文本。
下面给出了一个示例输入,可以有以下一个或多个:

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
  }
}

我想出了这个正则表达式:

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

我试图模仿这个:

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 

但显然这不能正常工作。如果我更改任何这些图层块中的类型,则不会检测到任何内容!甚至没有检测到type : "Data"

的图层

1 个答案:

答案 0 :(得分:1)

基于this post关于使用.net正则表达式进行括号匹配,您可以调整所呈现的正则表达式:

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

它正在寻找匹配()的匹配项,您可以简单地将它们换成{}(它们在该正则表达式中被转义的任何内容)。< / p>

然后你可以在layer\s*位前加上前缀。

对于排除type&lt;&gt;的块的功能"Data"我在您的示例中为pastebin中的所有其他type关键字添加了否定前瞻。不幸的是,为type: "Data"添加一个优先级前瞻功能根本不起作用,我认为如果确实如此,那将是您最强大的解决方案。

希望您有一个type值的有限列表,您可以扩展它以获得实用的解决方案:

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

在原始正则表达式中使用的关键位是[^()]+,它匹配正则表达式的其他组件匹配的括号内的内容。我已经将其改编为[^{}]+ - 成为“括号以外的所有内容” - 然后添加了长的“除了”子句,并且关键字不匹配。