python - 如何在 python 中使用正则表达式替换模式?

标签 python regex

我有一个看起来像这样的数据集:

Male    Name=Tony;  
Female  Name=Alice.1; 
Female  Name=Alice.2;
Male    Name=Ben; 
Male    Name=Shankar; 
Male    Name=Bala; 
Female  Name=Nina; 
###
Female  Name=Alex.1; 
Female  Name=Alex.2;
Male    Name=James; 
Male    Name=Graham; 
Female  Name=Smith;  
###
Female  Name=Xing;
Female  Name=Flora;
Male    Name=Steve.1;
Male    Name=Steve.2; 
Female  Name=Zac;  
###

我想更改列表,使其看起来像这样:

Male    Name=Class_1;
Female  Name=Class_1.1;
Female  Name=Class_1.2;
Male    Name=Class_1;
Male    Name=Class_1;
Male    Name=Class_1; 
Female  Name=Class_1;
###
Female  Name=Class_2.1; 
Female  Name=Class_2.2; 
Male    Name=Class_2; 
Male    Name=Class_2; 
Female  Name=Class_2;  
###
Female  Name=Class_3; 
Female  Name=Class_3; 
Male    Name=Class_3.1; 
Male    Name=Class_3.2; 
Female  Name=Class_3;
###

每个名称都必须更改为它们所属的类。 我注意到在数据集中,列表中的每个新类都用“###”表示。 所以我可以通过'###'将数据集分成 block 并计算###的实例。然后使用正则表达式查找名称,并将它们替换为### 的计数。

我的代码是这样的:

blocks = [b.strip() for b in open('/file', 'r').readlines()]
pattern = r'Name=(.*?)[;/]'
prefix = 'Class_'
triple_hash_count = 1

for line in blocks:
    match = re.findall(pattern, line)
    print match

for line in blocks:
    if line == '###':
        triple_hash_count += 1
        print line 
    else: 
        print(line.replace(match, prefix + str(triple_hash_count))) 

这似乎无法完成工作 - 没有进行任何替换。

最佳答案

运行您提供的代码时,我得到了以下回溯输出:

print(line.replace(match, prefix + str(triple_hash_count))) 
TypeError: Can't convert 'list' object to str implicitly

错误发生是因为 type(match) 求值为一个列表。当我在 PDB 中检查此列表时,它是一个空列表。这是因为 match 有两个 for 循环超出了范围。因此,让我们将它们组合起来:

for line in blocks:
    match = re.findall(pattern, line)
    print(match)

    if line == '###':
        triple_hash_count += 1
        print(line) 
    else: 
        print(line.replace(match, prefix + str(triple_hash_count)))

现在您可以在match 中获取内容,但是仍然存在一个问题:re.findall 的返回类型是一个字符串列表。 str.replace(...)需要一个字符串作为它的第一个参数。

您可以作弊,并将有问题的行更改为 print(line.replace(match[0], prefix + str(triple_hash_count))) —— 但前提是您确定自己' 将在不是 ### 的每一行上找到正则表达式匹配项。一种更有弹性的方法是在尝试对其调用 str.replace() 之前检查是否有匹配项。

最终代码如下所示:

for line in blocks:
    match = re.findall(pattern, line)
    print(match)

    if line == '###':
        triple_hash_count += 1
        print(line) 
    else:
        if match: 
            print(line.replace(match[0], prefix + str(triple_hash_count)))
        else:
            print(line)

还有两件事:

  1. 在第 11 行,您弄错了变量名。它是 triple_hash_count,而不是 hash_count
  2. 此代码实际上不会更改第 1 行作为输入提供的文本文件。您需要将 line.replace(match, prefix + str(triple_hash_count)) 的结果写回文件,而不仅仅是打印它。

关于python - 如何在 python 中使用正则表达式替换模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43021202/

相关文章:

python - 为每个字符至少包含一次的字符串查找更简单的 Python RegEx

regex - 在第一个分隔符后使用填充零重命名 PowerShell 文件

java - 数据行与正则表达式模式不匹配

python - 线性回归实现中的问题

python - 提取不遵循模式python的数字

python - json.loads() 不保持秩序

python - 使用 Python 获取基于 IP 地址的邮政编码

c# - 正则表达式捕获句子中的确切单词

Java正则表达式问题

python - 如何修补 Flask View 调用的函数