【问题标题】:Read every line of a text and replace using regex (Python)读取文本的每一行并使用正则表达式(Python)替换
【发布时间】:2020-10-16 06:12:12
【问题描述】:

我正在尝试读取包含以相同模式开头但以不同数字结尾的字符串的文件。我想通过替换它们(用正则表达式)来缩短这些字符串并将它们写在不同的文件中。我正在尝试使用 re.sub(我不想使用拆分)。

原文件是这样的:

@C00127:132:CDTL1ACXX:11000(several digits...)
@C00127:132:CDTL1ACXX:55588(several digits...)
@C00127:132:CDTL1ACXX:99999(several digits...)

我的想法是编写一个新文件,其中包含字符串的保留模式(即“@C00127:132:CDTL1ACXX:”),后跟 前 5 个可变数字。所以我想了一个这样的脚本:

import re
general_ID = open("general_ID.txt", "w+")
x = raw_input('type the name of the fastq file that you wanna extract the IDs: ')
with open (x, 'rt') as myfile:   
    for line in myfile:
        general_ID.write(re.sub('@C00127:132:CDTL1ACXX:......+', '@C00127:132:CDTL1ACXX:.....', line))
general_ID.close()

当我运行这个脚本时,我的原始文件来自:

@C00127:132:CDTL1ACXX:11000(several digits...)
@C00127:132:CDTL1ACXX:55588(several digits...)
@C00127:132:CDTL1ACXX:99999(several digits...)
etc

这样结束:

C00127:132:CDTL1ACXX:.....
C00127:132:CDTL1ACXX:.....
C00127:132:CDTL1ACXX:.....
etc

【问题讨论】:

  • 你能提供预期的样本输出吗?
  • 假设我的原始文件包含:“@C00127:132:CDTL1ACXX:110052527274723423424”等等。我想检索“”@C00127:132:CDTL1ACXX:11005”,即前五个数字,在保守字符串之后(“”@C00127:132:CDTL1ACXX:“,存在于所有ID中,每个行)。
  • 请检查下面的答案,并考虑接受最适合您的解决方案的答案。

标签: python regex replace write


【解决方案1】:

你可以像这样使用正则表达式

@C00127:132:CDTL1ACXX:(\d{5})

请参阅regex demo。详情:

  • @C00127:132:CDTL1ACXX: - 文字文本
  • (\d{5}) - 第 1 组:五位数字

Python 代码:

import re, os
x = input('type the name of the fastq file that you wanna extract the IDs: ')
if os.path.isfile(x):
    with open("general_ID.txt", "w") as general_ID:
        with open (x, 'r') as myfile:   
            for line in myfile:
                m = re.search(r'@C00127:132:CDTL1ACXX:(\d{5})', line)
                if m:
                    general_ID.write( "{}\n".format(m.group(1)) )

【讨论】:

  • 感谢您对 Wiktor 的帮助。正则表达式可以有效地做我需要的事情,但我不确定为什么“general_ID.txt”被创建为空。我认为通过添加“general_ID.close()”(在代码末尾)可以使它工作,但它没有。我会考虑清楚的。
  • @YasserKhalil 只需使用inputraw_input 函数是在 Python 2 中构建的。它在版本 3 中已弃用。
  • @YasserKhalil with open (x, 'r') as myfile: 要求 x 是有效的文件路径。如果文件在当前目录,它可以只是文件名。
  • @YasserKhalil 是的,只要确保提供正确的文件路径即可。
  • @YasserKhalil 对不起,我现在真的很累 :)
【解决方案2】:

使用切片

解决这个问题不需要正则表达式。前缀有固定长度;只取每行的固定长度切片。

id_len = 5
prefix_len = len("C00127:132:CDTL1ACXX:")
keep_len = prefix_len + id_len

with open("general_ID.txt", "w+") as general_ID:
    x = raw_input('type the name of the fastq file that you wanna extract the IDs: ')

    with open (x, 'rt') as myfile:   
        for line in myfile:
            general_ID.write("{}\n".format(line[:keeplen]))

一个有用的工具可能会接受要写出的每一行的长度。或者可以查看前几行来自动确定公共前缀的长度。

【讨论】:

  • 感谢您的帮助。我将最后一行修改为:general_ID.write (f"{line[:37]}\n") 因为我要检索的长度是固定的。但是python指责最后一个引号是无效的语法。对此有什么想法吗?谢谢。
  • 我刚刚意识到您使用的是 Python 2(Python 3 没有 raw_input)。我不认为 Python 2 有 f 字符串。我把最后一行改成{}\n".format(line[:keeplen])
猜你喜欢
  • 2015-02-21
  • 2021-10-11
  • 2017-10-18
  • 1970-01-01
  • 2014-05-12
  • 2014-03-11
  • 2018-12-04
相关资源
最近更新 更多