python文件中空格和换行符的捕获和文本文件的转存

之前公司的项目中,需要在嵌入式系统中实现一个http的网页端内容,由于项目历史遗留问题,公司是采用的将html文件转成c语言头文件的方式,每次修改页面端都需要从新编译一下程序,非常的繁琐。

虽然繁琐,但是因为历史遗留问题,历史遗留项目都采用这种方式做后面的升级维护。

入乡随俗嘛,用python写了一个html和h文件互转的小程序,程序编写的过程和原理很简单,以后有时间再另外发帖。(TODO)在此不做深入讨论。

程序也很好用,但是最近将公司自己写的程序使用gitblit本地仓库的形式进行版本管理后,发现一个致命的问题。就是每次转换成的h文件和公司历史遗留的文件进行git diff 时候,满屏都是不一样的地方。这咋利于版本控制和验证呢?

1. 问题分析

究竟是哪里不同呢?后来发现原来我写的转换脚本,和公司惯用的html to c脚本有着严重不同的地方在于:

公司旧版本程序是:
在这里插入图片描述
我转换的程序是:
在这里插入图片描述
git diff 比对文件的时候是会比对空格的,而且是引号的位置不同,所以就是大段的内容是不一样的。

这怎么办呢?

这时候正则匹配就派上用场了。

2. 寻找方法

上述问题其实总结起来就是:“引号位置放错了”。那么怎么知道应该在哪里放置引号呢?博主想到的笨办法就是在把每行的内容单独拎出来,然后分成三个部分,空格+内容+空格的方式,然后在组合成 空格+引号 +内容+引号+空格的方式。然后实际上就是提取出来了内容两边的东西。

talk is cheap , show codes.

假设我们有一个 test.html 文件:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <h1>Hello World</h1>
</body>
</html>

我们读取它的时候,要注意,每行实际在末尾有一个换行符\n

现在我们编写一个 r.py 脚本

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
 import re
 with open('test.html') as f:
     lines = f.readlines() # 获取行列表信息
     print(lines) # 打印行信息

我们在ipython中执行是这样的:

 In [31]: %run r.py
 ['<!DOCTYPE html>\n', '<html lang="en">\n', '<head>\n', '\t<meta charset="UTF-8"
 >\n', '\t<title>Document</title>\n', '</head>\n', '<body>\n', '\t<h1>Hello Wor
 ld</h1>\n', '</body>\n', '</html>']

2,3,4 表示的是每行的信息,和我们上面的 test.html 文件是一致的。

将上面的列表整理一下:

# 整理列表
[
'<!DOCTYPE html>\n',
'<html lang="en">\n',
'<head>\n',
'\t<meta charset="UTF-8">\n',
'\t<title>Document</title>\n',
'</head>\n', '<body>\n',
'\t<h1>Hello World</h1>\n',
'</body>\n', '</html>'
]

可以看出,我们就是逐行打印了文件内容而已:

拿第6行举例,我们需要匹配到\t 和 \n 并在合适的地方加上引号,程序就over了。

查阅正则内容(菜鸟教程Python正则表达式章节),可知道 \s 可以匹配任意空白字符。
在这里插入图片描述
于是,我们用行6字符串测试一下我们的处理代码对不对:

In [54]: s = re.search(r'^(\s*)(.*)(\s*)$','\t"<title>Document</title>"\n')

In [55]: s.group()
Out[55]: '\t"<title>Document</title>"\n'

In [56]: s.group(0)
Out[56]: '\t"<title>Document</title>"\n'

In [57]: s.group(1)
Out[57]: '\t'

In [58]: s.group(2)
Out[58]: '"<title>Document</title>"'

In [59]: s.group(3)
Out[59]: '\n'

在这里插入图片描述
测试和之前的想法是一致的。括弧括起来的内容被捕获出来。

3. 解决问题

由此,上述问题基本已经找到解决的头绪,那么定下代码编写的流程:

  • 读取读文件
  • 行列表信息行处理
  • 读取写文件
  • 写入处理后的行列表信息

于是编写代码:

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
import re # 引入正则库
with open('test.html') as f: # 读取读文件
    lines = f.readlines() # 读取行信息
    r = r'^(\s*)(.*)(\s*)$' # 正则
    lines = [re.search(r,l).group(1) +'"'+ re.search(r,l).group(2)+'\\n"'+re.search(r,l).group(3) for l in lines] # 处理行信息
    with open('test.h','w+') as f2: # 读取写文件
        f2.writelines(lines) # 写入行信息

其中第4行就是我们处理行信息的过程,这里用了一个列表推导式

所谓列表推导式,就是一种for循环的简写形式,可以从一个列表,经过一定的变换,快速生成一个列表。例如:

In[1]   :  a = [1,2,3,4]
In[2]   :  print(a)
Out[1]  :  [1,2,3,4]

In[3]   :  print([i for i in a])
Out[2]  :  [1,2,3,4]

In[4]   :  print([i*2+1 for i in a])
Out[3]  :  [3,5,7,9]

也就是,前面第4行的程序实际上就是将lines的数据单个处理,在捕获内容中加入一些我们需要的字符,比如是双引号,然后组成了新的列表。写入到文件中。

问题解决。

4. 总结

这个测试脚本的重点就在于正则的捕获,正则捕获在文本文件、字符串处理中使用广泛,需要不断积累和总结,方能领悟其中的妙用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值