2017-09-13 34 views
2

我有一個軟件可以分析Verilog路徑並負責將這些路徑映射到一系列對象。問題是找到一個正則表達式來分割實例名稱序列中的Verilog路徑。使用Python在不同實例中分割verilog路徑的正則表達式模式

Verilog路徑是Verilog標識符與點連接的序列。每個標識符都是一個實例名稱。 「。」 A.B.C中的關係表示在模塊層次結構中,A是父項,B是A的子項之一。C是B的子項之一。

每個Verilog路徑標識模塊層次結構中的唯一實例。

僞代碼:

Verilog Identifier A 
Verilog Identifier B 
Verilog Identifier C 

路徑父B的實例C作爲A的孩子:

A.B.C 

現在,問題是Verilog的標識符可以是「字母的順序,數字,下劃線(_)和美元符號($)。標識符的第一個字符只能是字母或下劃線「如本頁所述:http://verilog.renerta.com/source/vrg00018.htm

這種情況的Python將能夠僅通過寫拆分路徑:

>>> path = "a.verilog.path" 
>>> print path.split(".") 
['a', 'verilog', 'path'] 

不幸的是標識符可以逃脫標識符

轉義標識符以反斜槓開始並以空格結束。在反斜槓和空格中,可以有任何字符(空格除外),即使是點!

\an_escaped_identifier_that_ends_with_space 
\another-identifier,withsome.dots)insideit_ending_withspace 

因此,事情變得更加複雜,你不能再依賴分裂了。 下面是一個例子:

Verilog Identifier identifier1 
Verilog Identifier \escaped.identifier_2 
Verilog Identifier identifier3 

路徑父\ escaped.identifier_2實例標記位是標記位的子:

identifier1.\escaped.identifier_2 .identifier3 

那麼,我們如何可以使用Python re模塊來解決所有可能的Verilog路徑由任意數字標識符和/或轉義標識符組成?

+0

基於公認的答案我想我錯過了你的問題的東西,沒有你只是想匹配個人的Verilog標識符或幫了你一個正則表達式模式想要某種解決方案來將路徑解析爲單個標識符? –

+0

好吧,我看到你現在正在努力改進這個答案,一般來說,SO的策略是不接受答案,除非你覺得它完全回答你的問題,甚至是持續24小時。一旦一個問題有一個被接受的答案,大多數用戶,比如我,就不會回答這個問題。有可能最快的答案可能相當不錯,但有更多時間的答案最終會變得更好。 https://meta.stackexchange.com/questions/9731/fastest-gun-in-the-west-problem –

+0

我明白了,我同意。那麼關掉嘀嗒或保持現在的狀態是否更好? – auserdude

回答

1

([a-z_][a-z0-9$_]*|\\\S*)應該匹配常規和轉義標識符。

https://regex101.com/r/IxLakb/2

+0

這似乎是一個很好的答案:假設路徑是有效的Verilog路徑,它似乎工作(我測試了一下)。現在我正試圖理解在解析之前需要完成的驗證路徑的可能檢查,但這也許是另一個問題。無論如何,豎起大拇指! – auserdude

+0

這有點複雜。我認爲這個可行,但是當正則表達式得到這麼長時間時,很難確定。 https://regex101.com/r/IxLakb/4 –

+0

我認爲我們可以通過添加完整的Python代碼並改進測試來完成答案。首先'導入re'然後執行're.compile(r「([a-z _] [a-z0-9 $ _] * | \\\ S *)」)。split(s)[1:-1] '[1:-1]在列表的開頭和結尾刪除空字符串。該列表現在由標識符和點分隔符組成。 – auserdude

1

一個去了解這個方法是使用正則表達式來代替內點逃脫與一些特殊標記的字符串,如||,然後再像以前那樣分拆上的點。如果你想要點回來的話,你可以用每個標識符中的點代替你的特殊標記。

喜歡的東西:

import re 

path="we_are_1.a_law_ab1ding_2.\path.yep.mhmmm_3 .nothing_to_s33_here_4" 
dot_mask=re.compile(r'(\\[A-Za-z_|]+)\.(?=[^\s]*\s)') 
masked_path=path 
while(re.search(dot_mask,masked_path) != None): 
    masked_path=re.sub(dot_mask,r'\g<1>||',masked_path) 

masked_identifiers=masked_path.split('.') 

unmask=re.compile(r'\|{2}') 
unmasked_identifiers = [] 
for i in range(0,len(masked_identifiers)): 
    unmasked_identifiers.append(re.sub(unmask,'.',masked_identifiers[i])) 

演示:https://repl.it/LEWa/1

+0

我認爲性能測試對於瞭解哪種方法,您的方法或正則表達式更快會有幫助。 – auserdude

+1

老實說,我認爲使用正則表達式作爲分割標記,然後清除列表中的''。''元素是更優雅的解決方案,我只是覺得這是另一種可以考慮的方法 –

+0

我剛剛創建了這個Gist https ://gist.github.com/auserdude/e528d06ee6dd12600e01bde17f23e2c7對單個正則表達式方法的一個小測試。在執行此操作時,它可用於在Python和C++之間進行定性性能比較。注意,和Python一樣,正則表達式的編譯需要很多時間,所以程序開始時只需要一次。 – auserdude

相關問題