我正在开发一个汇编程序并选择使用 Python 而不是 C(主要是因为 Python 可以处理列表,我想学习它)
我的问题是如何将文本文件的每一行拆分为元组的一部分?
例如测试文件是:
ADD R1,R2;
OR R1,R3;
并有代码将其解析为
UserProgram=[['ADD','R1','R2'],['OR','R1','R3']]
它还必须忽略分号后的注释。谢谢!
>>> s = "ADD R1,R2; OR R1,R3;"
>>> t1 = s.split(';')
>>> t1
['ADD R1,R2', ' OR R1,R3', '']
>>> UserProgram = [t.strip().replace(',', ' ').split(' ') for t in t1 if len(t) > 0]
>>> UserProgram
[['ADD', 'R1', 'R2'], ['OR', 'R1', 'R3']]
>>>
顺便说一句,方括号表示列表,而不是元组。
所以我们有一个这种格式的源文件。
我们想要文件中每一行的标记列表。
标记是在第一个分号之后切断所有内容并将其余部分拆分为逗号或空格的结果。我们可以通过用空格替换逗号来做到这一点,然后只用空格分割。
所以我们转向标准库。split
当您不给字符串拆分时,字符串的方法会在空格上拆分。该replace
方法允许我们用另一个子字符串替换一个子字符串(例如,','
用' '
)。要删除分号后的所有内容,我们可以partition
将其取出并取第一部分(结果的元素 0)。* 因此,对单个行的处理看起来像
line.partition(';')[0].replace(',', ' ').split()
然后我们只需对文件的每一行执行此操作。要获得将某些函数应用于源元素的结果列表,我们可以使用列表推导直接请求它(基本上我们描述了结果列表应该是什么样子)。Python 中的文件对象是行的有效来源;您可以对其进行迭代(这个概念可能对 C++ 程序员来说更熟悉)并且元素是文件的行。
所以我们需要做的就是打开文件(我们习惯性地使用with
块来管理文件)并生成列表:
with open('asm.s') as source:
parsed = [
line.partition(';')[0].replace(',', ' ').split()
for line in source
]
完毕。
* 或split
再次使用,但是当生成元素列表实际上不是您的目标时,我发现这不太清楚。
>>> import re
>>> [re.split('\W+', s.strip()) for s in 'ADD R1,R2; OR R1,R3;'.split(';') if s]
[['ADD', 'R1', 'R2'], ['OR', 'R1', 'R3']]
升级版:
python -m timeit -s "import re; regexp = re.compile('\W+');" "[regexp.split(s.strip()) for s in 'ADD R1,R2; OR R1,R3;'.split(';') if s]"
100000 loops, best of 3: 3.34 usec per loop
python -m timeit "[t.strip().replace(',', ' ').split(' ') for t in 'ADD R1,R2; OR R1,R3;'.split(';') if t]"100000 loops, best of 3: 2.1 usec per loop
顺便说一句,我的变种还不错,虽然有点慢
如果您的来源是这种格式
source="""
ADD R1,R2;
OR R1,R3;
"""
然后您可以简单地通过 splitlines() 线性拆分源,然后使用;
分隔符再次拆分,丢弃 ';' 之后的任何内容
sourcelines=[x.split(";")[0].replace(',',' ').split()
for x in source.splitlines() if x]
[['ADD', 'R1', 'R2'], ['OR', 'R1', 'R3']]
您还可以继续前进并将每个 ASM 源代码行拆分为 OP-Code 和单独的操作数。
[[token.split(',') for token in x.split(";")[0].split()]
for x in source.splitlines() if x]
你会得到类似的东西
[[['ADD'], ['R1', 'R2']], [['OR'], ['R1', 'R3']]]
>>>s = "ADD R1,R2; OR R1,R3;"
>>>[substr.split() for substr in s.replace(',',' ').split(';')[:-1]]
[['ADD', 'R1', 'R2'], ['OR', 'R1', 'R3']]