2017-06-17 76 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