使用Python解析文本文件

use*_*409 4 python parsing

我是Python的新手,我希望用它来解析文本文件.该文件具有以下格式的250-300行:

---- Mark Grey (mark.grey@gmail.com) changed status from Busy to Available @ 14/07/2010 16:32:36 ----
----  Silvia Pablo (spablo@gmail.com) became Available @ 14/07/2010 16:32:39 ----
Run Code Online (Sandbox Code Playgroud)

我需要将以下信息存储到该文件中所有条目的另一个文件(excel或文本)中

UserName/ID  Previous Status New Status Date Time
Run Code Online (Sandbox Code Playgroud)

所以我的结果文件看起来应该是这样的

Mark Grey/mark.grey@gmail.com  Busy Available 14/07/2010 16:32:36
Silvia Pablo/spablo@gmail.com  NaN  Available 14/07/2010 16:32:39
Run Code Online (Sandbox Code Playgroud)

提前致谢,

任何帮助将非常感激

Tim*_*ker 15

为了帮助您入门:

result = []
regex = re.compile(
    r"""^-*\s+
    (?P<name>.*?)\s+
    \((?P<email>.*?)\)\s+
    (?:changed\s+status\s+from\s+(?P<previous>.*?)\s+to|became)\s+
    (?P<new>.*?)\s+@\s+
    (?P<date>\S+)\s+
    (?P<time>\S+)\s+
    -*$""", re.VERBOSE)
with open("inputfile") as f:
    for line in f:
        match = regex.match(line)
        if match:
            result.append([
                match.group("name"),
                match.group("email"),
                match.group("previous")
                # etc.
            ])
        else:
            # Match attempt failed
Run Code Online (Sandbox Code Playgroud)

会得到一系列比赛的部分.然后,我建议您使用csv module以标准格式存储结果.


Mar*_*tos 6

import re

pat = re.compile(r"----\s+(.*?) \((.*?)\) (?:changed status from (\w+) to|became) (\w+) @ (.*?) ----\s*")
with open("data.txt") as f:
    for line in f:
        (name, email, prev, curr, date) = pat.match(line).groups()
        print "{0}/{1}  {2} {3} {4}".format(name, email, prev or "NaN", curr, date)
Run Code Online (Sandbox Code Playgroud)

这假设了空白,并假设每一行都符合模式.如果要优雅地处理脏输入,可能需要添加错误检查(例如检查pat.match()不返回None).


Ale*_*lli 6

感兴趣的两种RE模式似乎是......:

p1 = r'^---- ([^(]+) \(([^)]+)\) changed status from (\w+) to (\w+) (\S+) (\S+) ----$'
p2 = r'^---- ([^(]+) \(([^)]+)\) became (\w+) (\S+) (\S+) ----$'
Run Code Online (Sandbox Code Playgroud)

所以我会这样做:

import csv, re, sys

# assign p1, p2 as above (or enhance them, etc etc)

r1 = re.compile(p1)
r2 = re.compile(p2)
data = []

with open('somefile.txt') as f:
    for line in f:
        m = p1.match(line)
        if m:
            data.append(m.groups())
            continue
        m = p2.match(line)
        if not m:
            print>>sys.stderr, "No match for line: %r" % line
            continue
        listofgroups = m.groups()
        listofgroups.insert(2, 'NaN')
        data.append(listofgroups)

with open('result.csv', 'w') as f:
    w = csv.writer(f)
    w.writerow('UserName/ID Previous Status New Status Date Time'.split())
    w.writerows(data)
Run Code Online (Sandbox Code Playgroud)

如果我描述的两种模式不够通用,当然可能需要进行调整,但我认为这种通用方法很有用.虽然Stack Overflow上的许多Python用户非常不喜欢RE,但我发现它们对于这种实用的临时文本处理非常有用.

也许其他人想要将RE用于荒谬的用途,例如对CSV,HTML,XML的临时解析,以及许多其他类型的结构化文本格式(其中存在非常好的解析器),这可能是不喜欢的.而且,其他任务远远超出了RE的"舒适区",而是需要像pyparsing这样的可靠的通用解析器系统.或者在其他极端超级简单的任务中使用简单的字符串完美地完成(例如,我记得最近使用的SO问题而if re.search('something', s):不是if 'something' in s:! - ).

但是对于相当广泛的任务(不包括最简单的一端,以及在另一端解析结构化或有些复杂的语法)RE是合适的,使用它们确实没有错,我建议所有程序员至少要学习RE的基础知识.