工作中很少用正则表达式和json数据,但是偶尔一次用到老是会卡克,半天才能获得自己想要的东西,今天又遇到了一个,记录一下处理过程,加深印象。

工作目标

想从下面这个文本中取出所有类似于我框出来的数据,并存储为json文本。我第一想法是用bs4,取出option标签,然后处理一下字符串就可以了,这种比较简单,主要是想加深一下自己正则表达式的熟练度,因此这里使用正则表达式来匹配。
在这里插入图片描述

正则表达式写法

第一种写法

res = re.findall('000050-.*?<', text, re.DOTALL)

因为每个想要取的数据之前,都有000050-这串字符,因此用它来匹配开始,然后结尾处都有个<,因此用它来匹配末端,中间的.*?表示匹配任意长度的任意字符,并进行最短匹配。
看看匹配出来的东西:
在这里插入图片描述
基本达到想要的东西了,后面对字符串进行处理一下就可以了。

第二种写法

写法很多,我还想到了另外一种写法

res2 = re.findall('[0-9]{6}:.*?<', text)

我想要的东西是6个数字+:+一串汉字,汉字后面是<结尾,因此简化一下就可以写成上面的东西{6}表示6次匹配,看看结果
在这里插入图片描述
比第一种要更简约一点。
我深知这两种匹配方法都不是最简单有效的方法,学习之路还很漫长。

存储为json文件

对第一种写法进行处理

对字符串进行处理

先yao 对字符串进行处理:

for i in range(len(res)):
    res[i] = res[i][14:-1]
    res[i] = res[i].split(':')

先取出每行有用的数据,然后用:进行分割文本。
这样处理得到了一个下面的列表:
在这里插入图片描述

列表转字典

代码比较简单,就一行代码

xzqh = {"%s" % res[j][0]: "%s" % res[j][1] for j in range(len(res))}

这里是写了个循环,并用到了格式输出,写起来简单,但是不熟练的话还是挺费劲的
比如,我刚开始就写成了下面这样的代码

xzqh1 = {"%s: %s" % (res[j][0], res[j][1]) for j in range(len(res))}

看看二者的差异
在这里插入图片描述

xzqh的键、值都出来了,而xzqh1还只是个集合,主要还是自己没注意格式。

字典存储为json文件

代码如下:

xzqh_json = json.dumps(xzqh, ensure_ascii=False, indent=1)
with open('xzqh.json', 'w+') as f:
    f.write(xzqh_json)  

这里有好几个坑要注意

  1. 字典中有中文,ensure_ascii=False,这个就是避免不显示中文的写法;
  2. json文本很长,最好是一个键值对换一行,indent=1,这保证了换行。

好了,就这样吧,最后上一下完整代码

import re
import json

text = open('xzqh.txt', encoding='utf-8')
text = text.read()

res = re.findall('000050-.*?<', text, re.DOTALL)
for i in range(len(res)):
    res[i] = res[i][14:-1]
    res[i] = res[i].split(':')
    
# xzqh1 = {"%s: %s" % (res[j][0], res[j][1]) for j in range(len(res))}  
xzqh = {"%s" % res[j][0]: "%s" % res[j][1] for j in range(len(res))}
xzqh_json = json.dumps(xzqh, ensure_ascii=False, indent=1)
with open('xzqh.json', 'w+') as f:
    f.write(xzqh_json)  

res2 = re.findall('[0-9]{6}:.*?<', text)

不到20行,,,折腾了半天,费劲了。

GitHub 加速计划 / js / json
41.72 K
6.61 K
下载
适用于现代 C++ 的 JSON。
最近提交(Master分支:1 个月前 )
960b763e 4 个月前
8c391e04 7 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐