![](/img/trans.png)
[英]How to replace a substring with a regex pattern using regex in python?
[英]How to replace a pattern using regex in python?
我有一個如下所示的數據集:
Male Name=Tony;
Female Name=Alice.1;
Female Name=Alice.2;
Male Name=Ben;
Male Name=Shankar;
Male Name=Bala;
Female Name=Nina;
###
Female Name=Alex.1;
Female Name=Alex.2;
Male Name=James;
Male Name=Graham;
Female Name=Smith;
###
Female Name=Xing;
Female Name=Flora;
Male Name=Steve.1;
Male Name=Steve.2;
Female Name=Zac;
###
我想更改列表,所以它看起來像這樣:
Male Name=Class_1;
Female Name=Class_1.1;
Female Name=Class_1.2;
Male Name=Class_1;
Male Name=Class_1;
Male Name=Class_1;
Female Name=Class_1;
###
Female Name=Class_2.1;
Female Name=Class_2.2;
Male Name=Class_2;
Male Name=Class_2;
Female Name=Class_2;
###
Female Name=Class_3;
Female Name=Class_3;
Male Name=Class_3.1;
Male Name=Class_3.2;
Female Name=Class_3;
###
每個名稱都必須更改為它們所屬的類。 我注意到在數據集中,列表中的每個新類都用'###'表示。 所以我可以通過'###'將數據集拆分成塊,並計算###的實例。 然后使用正則表達式查找名稱,並將其替換為###的計數。
我的代碼看起來像這樣:
blocks = [b.strip() for b in open('/file', 'r').readlines()]
pattern = r'Name=(.*?)[;/]'
prefix = 'Class_'
triple_hash_count = 1
for line in blocks:
match = re.findall(pattern, line)
print match
for line in blocks:
if line == '###':
triple_hash_count += 1
print line
else:
print(line.replace(match, prefix + str(triple_hash_count)))
這似乎不起作用 - 沒有替換。
運行您提供的代碼時,我得到以下回溯輸出:
print(line.replace(match, prefix + str(triple_hash_count)))
TypeError: Can't convert 'list' object to str implicitly
發生錯誤是因為type(match)
評估為列表。 當我在PDB中檢查此列表時,它是一個空列表。 這是因為match
已超出范圍,有兩個for循環。 所以讓我們把它們結合起來:
for line in blocks:
match = re.findall(pattern, line)
print(match)
if line == '###':
triple_hash_count += 1
print(line)
else:
print(line.replace(match, prefix + str(triple_hash_count)))
現在你在match
獲得內容,但仍然存在一個問題: re.findall
的返回類型是一個字符串列表。 str.replace(...)
期望單個字符串作為其第一個參數。
你可以作弊,並改變要print(line.replace(match[0], prefix + str(triple_hash_count)))
的違規行print(line.replace(match[0], prefix + str(triple_hash_count)))
- 但這假設您確定要找到正則表達式匹配每一行都不是###
。 一種更有彈性的方法是在嘗試調用str.replace()
之前檢查是否有匹配。
最終代碼如下所示:
for line in blocks:
match = re.findall(pattern, line)
print(match)
if line == '###':
triple_hash_count += 1
print(line)
else:
if match:
print(line.replace(match[0], prefix + str(triple_hash_count)))
else:
print(line)
還有兩件事:
triple_hash_count
,而不是hash_count
。 line.replace(match, prefix + str(triple_hash_count))
的結果寫回文件,而不僅僅是打印它。 問題源於使用第二個循環(以及錯誤命名的變量)。 這會奏效。
import re
blocks = [b.strip() for b in open('/file', 'r').readlines()]
pattern = r'Name=([^\.\d;]*)'
prefix = 'Class_'
triple_hash_count = 1
for line in blocks:
if line == '###':
triple_hash_count += 1
print line
else:
match = re.findall(pattern, line)
print line.replace(match[0], prefix + str(triple_hash_count))
雖然你已經有了答案,但你可以用幾行來表達正常的表達式(它甚至可以是單行,但這不是很易讀):
import re
hashrx = re.compile(r'^###$', re.MULTILINE)
namerx = re.compile(r'Name=\w+(\.\d+)?;')
new_string = '###'.join([namerx.sub(r"Name=Class_{}\1".format(idx + 1), part)
for idx,part in enumerate(hashrx.split(string))])
print(new_string)
###
,並且在MULTILINE
模式下使用錨點^
和$
。 Name
之后查找可能的數字,將其捕獲到組1中(但是由於並非所有名稱都具有可選項,因此可以選擇)。 ###
拆分你的字符串並用enumerate()
迭代它,因此有一個計數器用於插入數字。 ###
加入結果列表。 new_string = '###'.join(
[re.sub(r'Name=\w+(\.\d+)?;', r"Name=Class_{}\1".format(idx + 1), part)
for idx, part in enumerate(re.split(r'^###$', string, flags=re.MULTILINE))])
一個演示說了超過幾千個單詞。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.