[英]using regex in python to extract specific strings from a text file
我有一個文本文件,其中包含來自 VDHL 代碼編譯的錯誤報告。 我想自動執行廣告[很少需要從該文件中提取一些數據。 我專門尋找位於“[Hierarchy: 'block_ram_inst.”之后的字符串。 在我的例子中是 block_ram_top 或 block_ram_top_1 及其文件路徑。 我還想提取該特定線路的端口名稱。
InOut-Report Error /drive/build/users/tempuser/MCpro/projectphase1/MCpro_phase_1/project227/test_prj/mem/pro_1/pro_1.srcs/sources/code/mem_gen/vhdlcode/ramblock.vhd 241 10 Port 'clk' is not registered [Hierarchy: 'block_ram_inst.block_ram_top']
InOut-Report Error /drive/build/users/tempuser/MCpro/projectphase1/MCpro_phase_1/project227/test_prj/mem/pro_1/pro_1.srcs/sources/code/mem_gen/vhdlcode/ramblock.vhd 113 10 Port 'dina[31:0]' is not registered [Hierarchy: 'block_ram_inst.block_ram_top_1']
InOut-Report Error /drive/build/users/tempuser/MCpro/projectphase1/MCpro_phase_1/project227/test_prj/mem/pro_1/pro_1.srcs/sources/code/mem_gen/vhdlcode/ramblock.vhd 325 10 Port 'clk' is not registered [Hierarchy: 'block_ram_inst.block_ram_top']
InOut-Report Error /drive/build/users/tempuser/MCpro/projectphase1/MCpro_phase_1/project227/test_prj/mem/pro_1/pro_1.srcs/sources/code/mem_gen/vhdlcode/ramblock.vhd 152 10 Port 'clk' is not registered [Hierarchy: 'block_ram_inst.block_ram_top_1']
InOut-Report Error /drive/build/users/tempuser/MCpro/projectphase1/MCpro_phase_1/project227/test_prj/mem/pro_1/pro_1.srcs/sources/code/mem_gen/vhdlcode/ramblock.vhd 318 10 Port 'wea[0]' is not registered [Hierarchy: 'block_ram_inst.block_ram_top']
InOut-Report Error /drive/build/users/tempuser/MCpro/projectphase1/MCpro_phase_1/project227/test_prj/mem/pro_1/pro_1.srcs/sources/code/mem_gen/vhdlcode/ramblock.vhd 289 10 Port 'clk' is not registered [Hierarchy: 'block_ram_inst.block_ram_top_1']
我已經編寫了一個代碼來提取位於層次結構和文件名之后的字符串..但是我無法提取文件的完整路徑和端口名。
這是我的代碼。
with open(filename,'r') as f:
targets = [line for line in f if "InOut-Report" in line]
filenames = []
data = []
for line in targets:
match = re.match(r"InOut-Report.*/([-A-Za-z0-9_://.]+).*\[Hierarchy: 'block_ram_inst\.(\w+)']", line)
if match:
filenames.append(match.group(1))
data.append(match.group(2))
print filenames
print data
我得到的 output 是
['ramblock.vhd', 'ramblock.vhd', 'ramblock.vhd', 'ramblock.vhd', 'ramblock.vhd', 'ramblock.vhd', 'ramblock.vhd', 'ramblock.vhd']
['block_ram_top', 'block_ram_top_1', 'block_ram_top', 'block_ram_top_1', 'block_ram_top', 'block_ram_top_1', 'block_ram_top', 'block_ram_top_1']
但我想在我的 output 中包含文件名的完整路徑……而不僅僅是文件名。 我還想從 sepearte 列表中的每一行中提取端口名稱。
把文件內容當成字符串,可以匹配正則表達式
r'(?m) ((?:\/[\w.]+)+) .* 'block_ram_inst\.([\w.]+)'\]$'
對於每個匹配項,路徑將保存在捕獲組 1 中,端口名稱將保存在捕獲組 2 中。
Python 的正則表達式引擎執行以下操作。
(?m)
[ ]
( : begin capture group 1
(?:\/[\w.]+) : match '/' then 1+ word chars or periods in a
non-capture group
+ : execute non-capture group 1+ times
) : end capture group 1
[ ].*[ ]. : match a space, then 0+ chars then ' .'
'block_ram_inst\. : match "'block_ram_inst."
([\w.]+) : match 1+ words characters of periods in capture
group 2
'\] : match "']"
$ : match end of string
我將上面的空格表示為包含空格 ( [ ]
) 的捕獲組,只是為了讓它們可見。
您發布的正則表達式似乎不起作用,但由於您的問題很明確,我嘗試使用以下正則表達式:
r"InOut-Report\s+Error\s+([-\w://.]+)\s+\d+\s+\d+\s+Port '(\w+)' is not registered \[Hierarchy: 'block_ram_inst\.(block_ram_top(?:_\d)?)'\]"
在這里看到它的實際效果
InOut-Report
:從字面上匹配該字符串,沒什么特別的。\s+
: \s
匹配任何空白字符(空格、制表符、換行符...), +
修飾符指定可以有 1 個或多個。([-\w://.]+)
: \w
表示任何字母數字或下划線 ( A-Za-z0-9_
)。 您還添加了破折號 ( -
)、冒號 ( :
、斜杠 ( /
) 和點 ( .
)。 現在我再次看到它,第二個斜杠是多余的(它是從你的問題中復制的)所以你可以只留下其中一個。 帶有修飾符[...]+
的方括號指定內部列表中的任何字符需要出現 1 次或多次。 被中括號(...)
包圍的意思是它是一個捕獲組,路徑。\s+
:見上文。\d+
:與上面類似,但\d
表示任何數字( 0-9
),因此這 1 個或多個數字。\s+
:見上文。\d+
:見上文。\s+
:見上文。Port '
:從字面上匹配該字符串,沒什么特別的。(\w+)
:第二個捕獲組 1 個或多個字母數字字符或下划線,端口名稱。' is not registered \[Hierarchy: 'block_ram_inst\.
: 從字面上匹配該字符串,我們只是轉義[
和.
因為它們有特殊含義,我們想要的是字面字符而不是特殊含義。(block_ram_top(?:_\d)?)
: block_ram_top
是文字字符串,沒什么特別的。 _\d
表示下划線后跟數字。 它們在非捕獲組(?:...)
內。 非捕獲組允許對部分進行分組,但不會像我們對路徑或端口名稱所做的那樣保存它們供以后使用。 在這種情況下,我們將它們分組以應用?
可以在后面找到的修飾符。 這意味着它可以是 0 次或 1 次。 那么(?:_\d)?
意味着可以有一個下划線后跟一個數字或沒有。 所有這些都被一個捕獲組(...)
包圍,該捕獲組會將其保存為第三個值。\]
:文字字符]
再次轉義以指定我們需要文字字符並且我們不將其用作特殊字符。您還可以進一步簡化它:
r"([-\w://.]+)[\s\d]+Port '(\w+)' is not registered \[Hierarchy: 'block_ram_inst\.(block_ram_top(?:_\d)?)'\]"
在這里看到它的實際效果
簡化只是與路徑和組\s+\d+\s+\d+\s+
之前的部分不匹配,因為[\s\d]+
只是將空格和數字視為一個整體,因為我們不需要捕獲數字。
在評論中提出了另一個修改:
r"([-\w://.]+)[\s\d]+Port '(\w+)' is not registered \[Hierarchy: 'block_ram_inst\.(\w+)'\]"
唯一的修改是在第三個捕獲組中,以前只采用block_ram_top
或block_ram_top_
后跟一個數字,現在考慮任何帶下划線的字母數字字符。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.