簡體   English   中英

使用正則表達式匹配和替換

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM