使用正则表达式替换文本文件中的多个实体

2024-10-02 12:25:50 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个包含多行记录的结构化文本文件。每个记录都应该有一个键唯一的字段。我需要通读一系列这些文件,找到非唯一键字段并用唯一值替换键值。你知道吗

我的脚本正在识别所有需要替换的字段。我将这些字段存储在字典中,其中键是非唯一字段,值是唯一值的列表。你知道吗

例如:

 {
 "1111111111" : ["1234566363", "5533356775", "6443458343"]
 }

我想做的是只读取每个文件一次,找到“1111111111”(dict key)的实例,用第一个键值替换第一个匹配,用第二个键值替换第二个匹配,等等

我试图使用一个正则表达式,但我不知道如何构造一个合适的RE而不在文件中循环多次

这是我当前的代码:

def multireplace(Text, Vars):
    dictSorted = sorted(Vars, key=len, reverse=True)
    regEx = re.compile('|'.join(map(re.escape, dictSorted)))
    return regEx.sub(lambda match: Vars[match.group(0)], Text)

text = multireplace(text, find_replace_dict)

这对单身汉很管用关键字:值组合但如果:值是列表,则无法编译:

return regEx.sub(lambda match: Vars[match.group(0)], Text , 1)
TypeError: sequence item 1: expected str instance, list found

有没有可能改变函数而不在一个文件中循环多次?你知道吗


Tags: 文件lambdakeytextre列表returnmatch
1条回答
网友
1楼 · 发布于 2024-10-02 12:25:50

看一看并通读评论。如果有任何不合理的地方请告诉我:

import re

def replace(text, replacements):
    # Make a copy so we don't destroy the original.
    replacements = replacements.copy()

    # This is essentially what you had already.
    regex = re.compile("|".join(map(re.escape, replacements.keys())))

    # In our lambda, we pop the first element from the array. This way,
    # each time we're called with the same group, we'll get the next replacement.
    return regex.sub(lambda m: replacements[m.group(0)].pop(0), text)

print(replace("A A B B A B", {"A": ["A1", "A2", "A3"], "B": ["B1", "B2", "B3"]}))

# Output:
# A1 A2 B1 B2 A3 B3

更新

若要帮助解决以下注释中的问题,请尝试此版本,它将确切地告诉您哪个字符串已用完替换项:

import re

def replace(text, replacements):

    # Let's make a method so we can do a little more than the lambda.
    def make_replacement(match):
        try:
            return replacements[match.group(0)].pop(0)
        except IndexError:
            # Print out debug info about what happened
            print("Ran out of replacements for {}".format(match.group(0)))
            # Re-raise so the process still exits.
            raise

    # Make a copy so we don't destroy the original.
    replacements = replacements.copy()

    # This is essentially what you had already.
    regex = re.compile("|".join(map(re.escape, replacements.keys())))

    # In our lambda, we pop the first element from the array. This way,
    # each time we're called with the same group, we'll get the next replacement.
    return regex.sub(make_replacement, text)

print(replace("A A B B A B A", {"A": ["A1", "A2", "A3"], "B": ["B1", "B2", "B3"]}))

# Output:
# A1 A2 B1 B2 A3 B3

相关问题 更多 >

    热门问题