2017-06-17 37 views
0

我想解析一个自定义的输入文件,我正在写一个模拟代码。它由具有属性,值的嵌套“对象”组成(请参阅链接)。使用正则表达式递归地考虑缩进级别

这里是an example file and the regex I am using currently

([^:#\n]*):?([^#\n]*)#?.*\n 

它使得每个匹配是一条线,具有两个捕获组,一个用于属性,另一个用于其值。它也从字符集中排除“#”和“:”,因为它们分别对应于注释分隔符和属性:值分隔符。

如何修改我的正则表达式以递归匹配结构?也就是说,如果第n + 1行的识别等级高于第n行,则应将其匹配为第n行匹配的子组。

我正在使用PCRE正则表达式格式的Octave。

+0

您是否正在生产fi你想解析的文件,还是你收到它,因为它是在这个例子中? – chapelo

+0

我生成它,但最终用户将不得不用它们自己的参数修改它,所以我想尽可能保持它简单和可读性。 –

+1

由于PCRE不支持捕获堆栈,所以您只能通过“case”标签获得巨大的匹配。然后您必须分割值并再次匹配相同的正则表达式。我认为最好是手动编写一个简单的解析器,并用它来完成,因为这样的格式应该非常简单。 –

回答

1

我问你是否可以控制数据格式,因为它是这样的,数据很容易用YAML而不是正则表达式解析。

唯一的问题是,对象没有很好地形成:

1)取regions对象,例如,它有很多的属性称为layer所有的人。我想你的意图是建立一个layer s的清单,而不是许多具有相同名称的财产。

2)现在考虑每个具有相应值的layer属性。每个layer之后是我认为属于每个图层的孤立属性。

有了这些想法。如果你按照YAML规则来形成你的对象,解析它将是一件轻而易举的事情。

我知道你在Octave工作,但考虑我对你的数据所做的修改,以及在这种情况下用python解析它是多么容易。

DATA你有现在

case : 
    name : tandem solar cell 
    options : 
     verbose : true 
     t_stamp : system 
    units : 
     energy : eV 
     length : nm 
     time : s 
     tension : V 
     temperature: K 
     mqty : mole 
     light : cd 
    regions : 
     layer : Glass 
      geometry: 
       thick : 80 nm 
       npoints : 10 
      optical : 
       nk_file : vacuum.txt 
     layer : FTO 
      geometry: 
       thick : 10 nm 
       npoints : 10 
      optical : 
       nk_file : vacuum.txt 

修改后的数据与YAML语法

case : 
    name : tandem solar cell 
    options : 
     verbose : true 
     t_stamp : system # a sample comment 
    units : 
     energy : eV 
     length : nm 
     time : s 
     tension : V 
     temperature: K 
     mqty : mole 
     light : cd 
    regions : 
     - layer : Glass # ADDED THE - TO MAKE IT A LIST OF LAYERS 
      geometry :  # AND KEEP INDENTATION PROPERLY 
       thick : 80 nm 
       npoints : 10 
      optical : 
       nk_file : vacuum.txt 
     - layer : FTO 
      geometry: 
       thick : 10 nm 
       npoints : 10 
      optical : 
       nk_file : vacuum.txt 

遵守只有这些指令你得到你的对象解析:

import yaml 
data = yaml.load(text) 

""" your data would be parsed as: 
{'case': {'name': 'tandem solar cell', 
      'options': {'t_stamp': 'system', 'verbose': True}, 
      'regions': [{'geometry': {'npoints': 10, 'thick': '80 nm'}, 
         'layer': 'Glass', 
         'optical': {'nk_file': 'vacuum.txt'}}, 
         {'geometry': {'npoints': 10, 'thick': '10 nm'}, 
         'layer': 'FTO', 
         'optical': {'nk_file': 'vacuum.txt'}}], 
      'units': {'energy': 'eV', 
        'length': 'nm', 
        'light': 'cd', 
        'mqty': 'mole', 
        'temperature': 'K', 
        'tension': 'V', 
        'time': 's'}}} 

""" 
+0

非常感谢,在matlab/octave中检索这个python dict的最好方法是什么? 我找不到在结构中将其转换的方法,但是我认为只要能够以一致的方式访问它们就足够了。 –

+0

我不认为你必须使用python。您应该为Octave使用YAML库并将其解析为适当的Octave数据结构。 – chapelo