输入
- 命令行参数规范如下:
$ python3 format.py <input.txt> <output.txt>
-
<input.txt>
:有待解析清洗的原始数据文本文件名称。 -
<output.txt>
:用于存储完成清洗后的格式化数据的新建文本文件名称。
输出
-
代码要求读取输入的文本文件(名称为程序的第一个参数
<input.txt>
),提取每一行的数字,并将其转换成
xxx-xxx-xxx
的格式后输出至指定文件。例如:
$ cat input.txt
3357^$*5033#*5
0&@6949@5*956
340980!381@
3938^917!*40
7063$45655#
73@$%7630$298^#
$ python3 format.py input.txt output.txt
$ cat output.txt
335-750-335
069-495-956
340-980-381
393-891-740
706-345-655
737-630-298
问题点:
1.完成文件读取:
在处理文件对象时,最好使用
with
关键字。优点是,子句体结束后,文件会正确关闭,即便触发异常也可以。而且,使用
with
相比等效的
try
–
finally
代码块要简短得多:
>>>
>>> with open('workfile') as f:
... read_data = f.read()
>>> # We can check that the file has been automatically closed.
>>> f.closed
True
如果没有使用
with
关键字,则应调用
f.close()
关闭文件,即可释放文件占用的系统资源。
f.read(size)
可用于读取文件内容,它会读取一些数据,并返回字符串(文本模式),或字节串对象(在二进制模式下)。
size
是可选的数值参数。省略
size
或
size
为负数时,读取并返回整个文件的内容;文件大小是内存的两倍时,会出现问题。
size
取其他值时,读取并返回最多
size
个字符(文本模式)或
size
个字节(二进制模式)。如已到达文件末尾,
f.read()
返回空字符串(
''
)。
>>>
>>> f.read()
'This is the entire file.\n'
>>> f.read()
''
f.readline()
从文件中读取单行数据;字符串末尾保留换行符(
\n
),只有在文件不以换行符结尾时,文件的最后一行才会省略换行符。这种方式让返回值清晰明确;只要
f.readline()
返回空字符串,就表示已经到达了文件末尾,空行使用
'\n'
表示,该字符串只包含一个换行符。
>>>
>>> f.readline()
'This is the first line of the file.\n'
>>> f.readline()
'Second line of the file\n'
>>> f.readline()
''
从文件中读取多行时,可以用循环遍历整个文件对象。这种操作能高效利用内存,快速,且代码简单:
>>>
>>> for line in f:
... print(line, end='')
...
This is the first line of the file.
Second line of the file
如需以列表形式读取文件中的所有行,可以用
list(f)
或
f.readlines()
。
f.write(string) 把 string 的内容写入文件,并返回写入的字符数。
>>>
>>> f.write('This is a test\n')
15
2.如何删除无关字符
Python 的re模块提供了re.sub用于替换字符串中的匹配项。
语法:
re.sub(pattern, repl, string, count=0, flags=0)
参数:
- pattern : 正则中的模式字符串。
- repl : 替换的字符串,也可为一个函数。
- string : 要被查找替换的原始字符串。
- count : 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配。
- flags : 编译时用的匹配模式,数字形式。
前三个为必选参数,后两个为可选参数。
实例
#!/usr/bin/python3 import re phone = “2004-959-559 # 这是一个电话号码”
# 删除注释 num = re.sub(r’#.*$’, “”, phone) print (“电话号码 : “, num)
# 移除非数字的内容 num = re.sub(r’\D’, “”, phone) print (“电话号码 : “, num)
以上实例执行结果如下:
电话号码 : 2004-959-559 电话号码 : 2004959559
3.如何插入字符‘-’
python字符串不能直接在内部插入,可以另写一个函数,我这里用了一个偷懒的方法,将字符串转化为列表,插入后再将列表转换为字符串(如直接输出列表会报错)
遇到的bug:
1.列表转换后的字符串字母之间间会出现空格
['3', '3', '5', '-', '7', '5', '0', '-', '3', '3', '5']
3 3 5 - 7 5 0 - 3 3 5
['0', '6', '9', '-', '4', '9', '5', '-', '9', '5', '6']
0 6 9 - 4 9 5 - 9 5 6
['3', '4', '0', '-', '9', '8', '0', '-', '3', '8', '1']
3 4 0 - 9 8 0 - 3 8 1
['3', '9', '3', '-', '8', '9', '1', '-', '7', '4', '0']
3 9 3 - 8 9 1 - 7 4 0
['7', '0', '6', '-', '3', '4', '5', '-', '6', '5', '5']
7 0 6 - 3 4 5 - 6 5 5
['7', '3', '7', '-', '6', '3', '0', '-', '2', '9', '8']
7 3 7 - 6 3 0 - 2 9 8
解决:原来再join的时候前面的双引号打成了单引号,就会是按单个字符输出
2.在for循环里嵌套with open output的时候,只会输出一行数据,未解决,将其换为open close结构
代码如下:
import sys
import re
fOut = open(sys.argv[2], 'w')
with open(sys.argv[1], "r") as fIn:
for line in fIn:
line = re.sub(r'\D', "", line) #remove the undigital string
new_line = list(line) #
new_line.insert(3, '-')
new_line.insert(7, '-')
print(new_line)
line = "".join(new_line)
print(line)
fOut.write(line + '\n')
fOut.close()