[英]Using regular expression to match and replace
有一個字符串 A 的列表,它與另一個字符串 B 的列表如何匹配。我想使用正則表達式將字符串 A 替換為匹配的字符串 B 的列表。 但是我沒有得到正確的結果。
解決方案應該是A == ["Yogesh","Numita","Hero","Yogesh"]
。
import re
A = ["yogeshgovindan","TNumita","Herohonda","Yogeshkumar"]
B=["Yogesh","Numita","Hero"]
for i in A:
for j in B:
replaced=re.sub('i','j',i)
print(replaced)
這個對我有用:
lst=[]
for a in A:
lst.append([b for b in B if b.lower() in a.lower()][0])
如果在 A 列表中找到元素,則返回列表 B 中的元素。 有必要比較小寫單詞。 添加[0]
是為了從理解列表中獲取字符串而不是列表。
如果循環B
,則不需要正則表達式; 您可以簡單地使用會員測試。
正則表達式可能會帶來更好的性能,因為成員資格測試將掃描A
中的每個字符串以查找B
中的每個字符串,從而導致O(len(A) * len(B) performance)
。
只要單個術語不包含任何元字符並且可以出現在任何上下文中,形成正則表達式的最簡單方法是將B
的條目與交替操作連接:
reTerms = re.compile('|'.join(B), re.I)
但是,為了安全起見,應首先對條目進行轉義,以防任何包含元字符:
# map-based
reTerms = re.compile('|'.join(map(re.escape, B)), re.I)
# comprehension-based
reTerms = re.compile('|'.join([re.escape(b) for b in B]), re.I)
如果對術語出現的上下文有任何限制,則需要將限制的子模式添加到模式之前並附加到模式中。 例如,如果術語必須顯示為完整的單詞:
reTerms = re.compile(f"\b(?:{'|'.join(map(re.escape, B))})\b", re.I)
可以將此正則表達式應用於A
的每個項目以獲取匹配的文本:
replaced = [reTerms.search(name).group(0) for name in A]
# result: ['yogesh', 'Numita', 'Hero', 'Yogesh']
由於正則表達式中的術語是直接字符串匹配,因此內容將是正確的,但大小寫可能不正確。 這可以通過規范化步驟來糾正,通過dict
傳遞匹配的文本:
normed = {term.lower():term for term in B}
replaced = [normed[reTerms.search(name).group(0).lower()] for name in A]
# result: ['Yogesh', 'Numita', 'Hero', 'Yogesh']
一個問題仍然存在:如果 A 的A
不匹配怎么辦? 然后reTerms.search
返回None
,它沒有group
屬性。 如果將None
-propagating 屬性訪問添加到 Python (例如PEP 505建議的),則可以使用以下方法輕松解決此問題:
names = ["yogeshgovindan","TNumita","Herohonda","Yogeshkumar", "hrithikroshan"]
normed[None] = None
replaced = [normed[reTerms.search(name)?.group(0).lower()] for name in names]
在沒有這種特征的情況下,有多種方法,例如使用三元表達式和海象賦值。 在下面的示例中,使用列表作為替代項來為匹配項提供默認值:
import re
names = ["yogeshgovindan","TNumita","Herohonda","Yogeshkumar", "hrithikroshan"]
terms = ["Yogesh","Numita","Hero"]
normed = {term.lower():term for term in terms}
normed[''] = None
reTerms = re.compile('|'.join(map(re.escape, terms)), re.I)
# index may need to be changed if `reTerms` includes any context
[normed[(reTerms.search(sentence) or [''])[0].lower()] for sentence in sentences]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.