如何使用字典执行多个搜索和替换操作?[重复]

2025-04-16 08:57:00
admin
原创
12
摘要:问题描述:我需要在地址栏中将“北”、“南”等文本替换为“N”、“S”等。我想创建一个字典来保存这些替换值。假设我们有:replacements = {'NORTH':'N','SOUTH':'S','EAST':'E','WEST':'W'} address = "123 north anywher...

问题描述:

我需要在地址栏中将“北”、“南”等文本替换为“N”、“S”等。我想创建一个字典来保存这些替换值。假设我们有:

replacements = {'NORTH':'N','SOUTH':'S','EAST':'E','WEST':'W'}
address = "123 north anywhere street"

我可以使用replacements字典进行所有替换吗?例如通过迭代它?这个代码是什么样的?


解决方案 1:

    address = "123 north anywhere street"
    
    for word, initial in {"NORTH": "N", "SOUTH": "S"}.items():
        address = address.replace(word.lower(), initial)
    print(address)

简洁、易读。

解决方案 2:

事实上你已经接近目标了:

dictionary = {"NORTH":"N", "SOUTH":"S" } 
for key in dictionary.iterkeys():
    address = address.upper().replace(key, dictionary[key])

注意:对于 Python 3 用户,您应该使用.keys()而不是.iterkeys()

dictionary = {"NORTH":"N", "SOUTH":"S" } 
for key in dictionary.keys():
    address = address.upper().replace(key, dictionary[key])

解决方案 3:

我认为还没有人建议的一个选项是构建一个包含所有键的正则表达式,然后简单地对字符串进行一次替换:

>>> import re
>>> l = {'NORTH':'N','SOUTH':'S','EAST':'E','WEST':'W'}
>>> pattern = '|'.join(sorted(re.escape(k) for k in l))
>>> address = "123 north anywhere street"
>>> re.sub(pattern, lambda m: l.get(m.group(0).upper()), address, flags=re.IGNORECASE)
'123 N anywhere street'
>>> 

这样做的好处是正则表达式可以忽略输入字符串的大小写而不对其进行修改。

如果您只想对完整的单词进行操作,那么您也可以通过对模式进行简单的修改来实现:

>>> pattern = r'({})'.format('|'.join(sorted(re.escape(k) for k in l)))
>>> address2 = "123 north anywhere southstreet"
>>> re.sub(pattern, lambda m: l.get(m.group(0).upper()), address2, flags=re.IGNORECASE)
'123 N anywhere southstreet'

解决方案 4:

您可能正在寻找iteritems()

d = {'NORTH':'N','SOUTH':'S','EAST':'E','WEST':'W'}
address = "123 north anywhere street"

for k,v in d.iteritems():
    address = address.upper().replace(k, v)

地址现在是'123 N ANYWHERE STREET'


好吧,如果您想保留大小写、空格和嵌套单词(例如,Southstreet不应转换为Sstreet),请考虑使用这个简单的列表理解:

import re

l = {'NORTH':'N','SOUTH':'S','EAST':'E','WEST':'W'}

address = "North 123 East Anywhere Southstreet    West"

new_address = ''.join(l[p.upper()] if p.upper() in l else p for p in re.split(r'(W+)', address))

new_address 现在是

N 123 E Anywhere Southstreet    W

解决方案 5:

使用字典“翻译”字符串是一个非常常见的需求。我建议你在你的工具箱里保留一个函数:

def translate(text, conversion_dict, before=None):
    """
    Translate words from a text using a conversion dictionary

    Arguments:
        text: the text to be translated
        conversion_dict: the conversion dictionary
        before: a function to transform the input
        (by default it will to a lowercase)
    """
    # if empty:
    if not text: return text
    # preliminary transformation:
    before = before or str.lower
    t = before(text)
    for key, value in conversion_dict.items():
        t = t.replace(key, value)
    return t

然后你可以写:

>>> a = {'hello':'bonjour', 'world':'tout-le-monde'}
>>> translate('hello world', a)
'bonjour tout-le-monde'

解决方案 6:

我建议使用正则表达式,而不是简单的替换。使用替换可能会出现单词部分被替换的风险,这可能并非你想要的结果。

import json
import re

with open('filePath.txt') as f:
   data = f.read()

with open('filePath.json') as f:
   glossar = json.load(f)

for word, initial in glossar.items():
   data = re.sub(r'' + word + r'', initial, data)

print(data)

解决方案 7:

如果您正在寻找一种简洁的方法,您可以从 functools 中选择 reduce:

from functools import reduce

str_to_replace = "The string for replacement."
replacement_dict = {"The ": "A new ", "for ": "after "}

str_replaced = reduce(lambda x, y: x.replace(*y), [str_to_replace, *list(replacement_dict.items())])
print(str_replaced)

解决方案 8:

def replace_values_in_string(text, args_dict):
    for key in args_dict.keys():
        text = text.replace(key, str(args_dict[key]))
    return text

解决方案 9:

尝试,

import re
l = {'NORTH':'N','SOUTH':'S','EAST':'E','WEST':'W'}

address = "123 north anywhere street"

for k, v in l.iteritems():
    t = re.compile(re.escape(k), re.IGNORECASE)
    address = t.sub(v, address)
print(address)

解决方案 10:

使用replace()format()都不是那么精确:

data =  '{content} {address}'
for k,v in {"{content}":"some {address}", "{address}":"New York" }.items():
    data = data.replace(k,v)
# results: some New York New York

'{ {content} {address}'.format(**{'content':'str1', 'address':'str2'})
# results: ValueError: unexpected '{' in field name

re.sub()如果您需要精确的位置,最好使用以下方式翻译:

import re
def translate(text, kw, ignore_case=False):
    search_keys = map(lambda x:re.escape(x), kw.keys())
    if ignore_case:
        kw = {k.lower():kw[k] for k in kw}
        regex = re.compile('|'.join(search_keys), re.IGNORECASE)
        res = regex.sub( lambda m:kw[m.group().lower()], text)
    else:
        regex = re.compile('|'.join(search_keys))
        res = regex.sub( lambda m:kw[m.group()], text)

    return res

#'score: 99.5% name:%(name)s' %{'name':'foo'}
res = translate( 'score: 99.5% name:{name}', {'{name}':'foo'})
print(res)

res = translate( 'score: 99.5% name:{NAME}', {'{name}':'foo'}, ignore_case=True)
print(res)

解决方案 11:

所有这些答案都很好,但是您缺少 python 字符串替换 - 它简单快捷,但要求您的字符串格式正确。

address = "123 %(direction)s anywhere street"
print(address % {"direction": "N"})

解决方案 12:

处理此问题的更快方法是尊重单词边界并仅在字典中查找每个标记一次:

token_mapping = {
    'north': 'N', 'south': 'S', 
    'east': 'E', 'west': 'W'
    'street': 'St',
    }

def tokenize(text):
    return text.lower().split()

def detokenize(tokens):
    return ' '.join(tokens)

def replace_tokens(text, token_mapping=token_mapping):
    input_tokens = tokenize(text)
    output_tokens = []
    for tok in input_tokens:
        output_tokens.append(token_mapping.get(tok, tok))
    return detokenize(output_tokens)
>>> replace_tokens("123 north anywhere street")
'123 N anywhere St'

这种方法的另一个优点是,您可以折叠单个令牌的情况以满足您的需要:

def detokenize(tokens):
    return ' '.join([t.title() for t in tokens])
>>> replace_tokens("123 north anywhere street")
'123 N Anywhere St'

这是网络规模 NLP 使用的方法,包括拼写纠正器和缩写扩展器/收缩器。

解决方案 13:

Duncan 方法的优点在于它能小心地避免覆盖之前的答案。例如,如果你有 {"Shirt": "Tank Top", "Top": "Sweater"},其他方法会将“Shirt”替换为“Tank Sweater”。

以下代码扩展了该方法,但对键进行排序,以便始终首先找到最长的键,并且使用命名组进行不区分大小写的搜索。

import re
root_synonyms = {'NORTH':'N','SOUTH':'S','EAST':'E','WEST':'W'}
# put the longest search term first. This menas the system does not replace "top" before "tank top"
synonym_keys = sorted(root_synonyms.keys(),key=len,reverse=True)
# the groups will be named w1, w2, ... . Determine what each of them should become
number_mapping = {f'w{i}':root_synonyms[key] for i,key in enumerate(synonym_keys) }
# make a regex for each word where "tank top" or "tank  top" are the same
search_terms = [re.sub(r's+',r's+',re.escape(k)) for k in synonym_keys]
# give each search term a name w1 etc where
search_terms = [f'(?P<w{i}>\\b{key}\\b)' for i,key in enumerate(search_terms)]
# make one huge regex
search_terms = '|'.join(search_terms)
# compile it for speed
search_re = re.compile(search_terms,re.IGNORECASE)

query = "123 north anywhere street"
result = re.sub(search_re,lambda x: number_mapping[x.lastgroup],query)
print(result)
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2482  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1533  
  PLM(产品生命周期管理)项目对于企业优化产品研发流程、提升产品质量以及增强市场竞争力具有至关重要的意义。然而,在项目推进过程中,范围蔓延是一个常见且棘手的问题,它可能导致项目进度延迟、成本超支以及质量下降等一系列不良后果。因此,有效避免PLM项目范围蔓延成为项目成功的关键因素之一。以下将详细阐述三大管控策略,助力企业...
plm系统   0  
  PLM(产品生命周期管理)项目管理在企业产品研发与管理过程中扮演着至关重要的角色。随着市场竞争的加剧和产品复杂度的提升,PLM项目面临着诸多风险。准确量化风险优先级并采取有效措施应对,是确保项目成功的关键。五维评估矩阵作为一种有效的风险评估工具,能帮助项目管理者全面、系统地评估风险,为决策提供有力支持。五维评估矩阵概述...
免费plm软件   0  
  引言PLM(产品生命周期管理)开发流程对于企业产品的全生命周期管控至关重要。它涵盖了从产品概念设计到退役的各个阶段,直接影响着产品质量、开发周期以及企业的市场竞争力。在当今快速发展的科技环境下,客户对产品质量的要求日益提高,市场竞争也愈发激烈,这就使得优化PLM开发流程成为企业的必然选择。缺陷管理工具和六西格玛方法作为...
plm产品全生命周期管理   0  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用