结合使用Python和Regex搜索包含特定单词的行,然后将这些行追加到CSV列标题

v2g6jxz6  于 2023-10-22  发布在  Python
关注(0)|答案(1)|浏览(141)

我有一个很长的文本文件名为'maps.txt'。它包含大量的数据,分为几个部分。每个部分都有自己的标题:

measured burnup - core  140828~a
*a bunch of data*

channel averaged  cell avg  fast fluxes   core 000124~a  k-eff: 1.028343 scale = 1e+14
*a bunch of data*

channel averaged  boundary  fast fluxes   core 000124~a  k-eff: 1.028343 scale = 1e+14
*a bunch of data*

scan 170210 fission power at tpd 223207.8   total power  112.210
*a bunch of data*

我想创建一个Python脚本,它遍历文件,使用Regex搜索标题中的一个单词,然后将该标题复制到CSV文件中用作列标题:

import re
import csv

outputFilename = Sitename + '_' + datetime.now().strftime('%Y%m%d__%H_%M_%S')
with open(outputFilename + '_output.csv', 'w') as outputCSV:
    search_titles = re.compile('channel|scan|measured')
    for i, line in enumerate(open('maps.txt', 'r')):
        for match in re.finditer(search_titles, line):
                writer = csv.writer(outputCSV).writerow(line)

这似乎可以很好地从数据的每个部分中搜索标题,但它不能正确地输出到CSV文件。相反,每个标题中的每个字母都有自己的单元格(我在Excel中打开CSV文件),并且不会将它们沿着打印在CSV文件的第一行(我希望将它们作为列标题)。而是返回并打印到下一行。
最后,我想截断标题,只保留一行列标题,如:

| measured burnup | channel averaged cell avg fast fluxes |  channel averaged  boundary  fast fluxes  |  scan 170210 fission power at tpd  |

但是,由于每个标题是一个不同的长度,我不知道如何做到这一点。

1zmg4dgp

1zmg4dgp1#

你之所以得到一行单个字符是因为这一行:

writer = csv.writer(outputCSV).writerow(line)

writerow需要“一个可迭代的字符串”,但你传递给它的是一个字符串,所以它会隐式地将其转换为一个列表,这会导致字符串被拆分为单个字符。
相反,您需要将所有头累积到一个列表中,并在完成阅读输入后将其写入文件:

with open(outputFilename + '_output.csv', 'w') as outputCSV:
    writer = csv.writer(outputCSV)
    search_titles = re.compile('channel|scan|measured')
    column_headings = []
    for line in open('maps.txt', 'r'):
        if search_titles.match(line):
            column_headings.append(line.strip())
    writer.writerow(column_headings)

请注意,由于不使用行号,因此不需要enumerate
在删除列名中不必要的部分方面,您需要找出哪些是相关的,并只匹配该部分。例如,给定样本数据,您可以使用如下正则表达式:

^\s*(?:channel.*?(?=\s+core)|scan.*tpd|measured.*?(?=\s+-\s+core))

然后将代码修改为search而不是match(以支持不在行首的匹配,尽管您可能不需要):

with open(outputFilename + '_output.csv', 'w') as outputCSV:
    writer = csv.writer(outputCSV)
    search_titles = re.compile('^\s*(?:channel.*?(?=\s+core)|scan.*tpd|measured.*?(?=\s+-\s+core))')
    column_headings = []
    for line in open('maps.txt', 'r'):
        m = search_titles.search(line)
        if m is not None:
            column_headings.append(m.group())
    writer.writerow(column_headings)

对于您的示例数据,这给出了一行:

measured burnup,channel averaged  cell avg  fast fluxes,channel averaged  boundary  fast fluxes,scan 170210 fission power at tpd

相关问题