Python中替换字符串时如何保留关联信息?
处理带关联信息的单词列表归一化问题
问题背景
我们有一组有序单词和对应的关联信息(可以是两个平行列表,或是(单词, 信息)的元组列表),需要执行归一化操作(比如缩写替换、数字转英文单词),同时保留每个归一化结果对应的原始关联信息。之前直接拼接成字符串用正则替换的方法会丢失位置关联,需要针对性处理。
示例输入:
words = ["hello", "I", "am", "I", "am", "Jone", "101"] info = ["1", "3", "23", "4", "6", "5", "12"] # 或元组列表形式 list_tuples = list(zip(words, info))
我们需要得到两种可能的归一化结果:
结果一:合并关联信息到列表
归一化后的合并单词对应原始多个单词的关联信息列表,单个替换的单词保留原信息:
words = ["hello", "I'm", "I'm", "Jone", "one hundred and one"] info = ["1", ["3", "23"], ["4", "6"], "5", "12"]
结果二:拆分归一化后的多词内容
将归一化后的多词内容拆分为单个单词,每个单词重复原始关联信息:
words = ["hello", "I'm", "I'm", "Jone", "one", "hundred", "and", "one"] info = ["1", ["3", "23"], ["4", "6"], "5", "12", "12", "12", "12"]
解决方案实现
通用思路
核心是遍历单词序列时,识别需要匹配的规则(单词或多词组合),同步处理对应的关联信息,而非先拼接成字符串丢失位置信息。我们可以定义规则列表,每个规则包含匹配的单词序列和替换内容,再按顺序遍历处理。
实现结果一:合并关联信息
def normalize_merge_info(word_info_tuples): # 定义归一化规则:(匹配的单词元组, 替换后的单词) rules = [ (("I", "am"), "I'm"), (("101",), "one hundred and one") ] result_words = [] result_info = [] i = 0 n = len(word_info_tuples) while i < n: matched = False # 遍历所有规则,尝试匹配当前位置的单词序列 for pattern, replacement in rules: pattern_len = len(pattern) # 检查当前位置到后续是否足够匹配规则长度 if i + pattern_len <= n: # 提取当前位置的单词序列 current_words = tuple(word for word, _ in word_info_tuples[i:i+pattern_len]) if current_words == pattern: # 匹配成功,添加替换后的单词 result_words.append(replacement) # 收集对应的关联信息列表 collected_info = [info for _, info in word_info_tuples[i:i+pattern_len]] # 单词规则保留单个信息,多词规则保留列表 result_info.append(collected_info if pattern_len > 1 else collected_info[0]) i += pattern_len matched = True break # 无匹配规则时,直接添加原单词和信息 if not matched: word, info = word_info_tuples[i] result_words.append(word) result_info.append(info) i += 1 return result_words, result_info # 测试 words = ["hello", "I", "am", "I", "am", "Jone", "101"] info = ["1", "3", "23", "4", "6", "5", "12"] list_tuples = list(zip(words, info)) res_words, res_info = normalize_merge_info(list_tuples) print(res_words) print(res_info)
输出:
["hello", "I'm", "I'm", "Jone", "one hundred and one"] ["1", ["3", "23"], ["4", "6"], "5", "12"]
实现结果二:拆分多词替换内容
在结果一的基础上,对替换后的内容进行拆分,多词内容拆分为单个单词,同时重复对应的关联信息:
def normalize_split_words(word_info_tuples): rules = [ (("I", "am"), "I'm"), (("101",), "one hundred and one") ] result_words = [] result_info = [] i = 0 n = len(word_info_tuples) while i < n: matched = False for pattern, replacement in rules: pattern_len = len(pattern) if i + pattern_len <= n: current_words = tuple(word for word, _ in word_info_tuples[i:i+pattern_len]) if current_words == pattern: # 拆分替换后的内容为单个单词 split_replacement = replacement.split() # 获取对应的关联信息(多词规则取列表,单词规则取单个) source_info = [info for _, info in word_info_tuples[i:i+pattern_len]] source_info = source_info if pattern_len > 1 else [source_info[0]] # 处理拆分后的每个单词 for word_part in split_replacement: result_words.append(word_part) # 合并规则保留信息列表,拆分规则重复原始单条信息 result_info.append(source_info if pattern_len > 1 else source_info[0]) i += pattern_len matched = True break # 无匹配规则时,直接添加原单词和信息 if not matched: word, info = word_info_tuples[i] result_words.append(word) result_info.append(info) i += 1 return result_words, result_info # 测试 res_words2, res_info2 = normalize_split_words(list_tuples) print(res_words2) print(res_info2)
输出:
["hello", "I'm", "I'm", "Jone", "one", "hundred", "and", "one"] ["1", ["3", "23"], ["4", "6"], "5", "12", "12", "12", "12"]
扩展说明
- 可根据需求添加更多规则,比如
(("we'll",), "we will")或(("you", "are"), "you're"),只需在rules列表中添加对应条目即可。 - 如果规则有优先级(比如长规则优先匹配),可将长规则放在
rules列表的前面,避免短规则先匹配导致长规则无法触发。
内容的提问来源于stack exchange,提问作者ivangtorre
相关产品推荐
相关产品推荐

