1、问题出现
需要提取一份xml文件中参数名和参数值,格式如下:
true
我们需要的字段如上,红色部分为参数名,蓝色部分为参数值,当然,实际文档中还有很多干扰因素。
步骤为先打开文件,然后用正则表达式匹配到我们需要的母项(r"
期间发生了一个问题,调试的时候我使用的一小段样本如下:
480ms
disabled
320ms
480ms
1024ms
6
使用的正则表达式为:
p1 = r"((?<=\")\w+(?=\"))" #p1为查找的参数名正则表达式
p2 = r"(?<=\>)\w+(?=\
pattern1 = re.compile(p1)
pattern2 = re.compile(p2)
get =pattern1.findall(line)[0]
get2=pattern2.findall(line)[0]
lncel1_pa.append(get)
lncel1_va.append(get2)
调试过程是完全正常的,匹配数字和文字即可,也是没问题的,然而在真正运行打开整个文档过程中出现了如下报错:
1 File "E:/pgtool/Files/filesprocess.py", line 32, in
2 get2=pattern2.findall(line)[0]3
4 IndexError: list index out of range
也就意味着在提取参数值过程中list[0]都已经超出了范围,也就是这个list是空的,这是哪里出了问题呢?
经过spyder的debug功能调试,逐行运行,终于发现了问题所在,即在提取参数中我们使用的是 r"(?<=\>)\w+(?=\108
大于号小于号之间的文字和数字(此处得到的值为108)。但某些参数值存在空格,而且空格类型不止一种,有1个空格的,也有多个空格间隔的,如下:
6 db
PRBs with PSS or SSS and PBCH used
以至于出现了正则表达式匹配不到。
2、根据此问题做的优化
考虑到有空格存在所以进行了第一次正则表达式改进:\w+ ?
p2 = r"(?<=\>)\w+(?=\
修改为-->p2= r"(?<=\>)\w+ ?(?=\
但这种优化对
6 db
这类有一个空格或者没有空格的才能匹配,对于
PRBs with PSS or SSS and PBCH used
还是不能匹配(间隔多个空格类型),于是进行了第二次优化,将匹配参数值的正则表达式改为.*,也就是在大于号与小于号之间的参数值匹配为任意值(除换行外),问题彻底解决。
p2 = r"(?<=\>)\w+(?=\
修改为-->p2= r"(?<=\>).*(?=\
3、进一步优化
当然,为了避免出现两行重叠问题而带来的贪婪匹配问题,我们需要在.*后添加一个?号来避免贪婪匹配
p2 = r"(?<=\>)\w+(?=\
修改为-->p2= r"(?<=\>).*?(?=\
目前完整的代码也仅仅只能匹配一个LNCEL下的参数,后续我们将进一步编辑,可提取其他LNCEL下的参数,大致的思路为:为各个LNCEL参数提取后都放置到一个DataFrame中,然后再进行水平联结,最后转入excel中。
4、完整代码如下
代码:
#-*- coding: utf-8 -*-
"""Created on Thu Jul 12 15:19:37 2018
@author: lishuixing_nok"""
importreimportnumpy as npimportpandas as pd
fp=open('gudi.xml')
line=fp.readline()#print (line)
lncel1_pa=[]
lncel1_va=[]
lncel2=[]
lncel3=[]
cels=[]whileline:if re.match(r"
k=re.search(r"(LNBTS-)(\d+)(/LNCEL)(-\d+)",line).group(2)+re.search(r"(LNBTS-)(\d+)(/LNCEL)(-\d+)",line).group(4)
cels.append(k)elif (re.match(r"
",line)):break
else:if re.match(r"
).*?(?=\
pattern2=re.compile(p2)
get=pattern1.findall(line)[0]
get2=pattern2.findall(line)[0]
lncel1_pa.append(get)
lncel1_va.append(get2)else:passline=fp.readline()
fp.close()#print (lncel1_pa,'\n',lncel1_va) 打印参数和
pd1=pd.DataFrame(lncel1_va,index=lncel1_pa,columns=cels)
pd1.index.name='parameter'
print(pd1)
pd1.to_excel(r'E:\pgtool\Files\lncelvalue.xlsx',sheet_name='lncel')
提取文档样本:
480ms
disabled
320ms
480ms
1024ms
6
640ms
320ms
640ms
640ms
1
false
openAccess
64n
98
PRBs with PSS or SSS and PBCH used
30
30
3
1
1
16
true
fc4
fc2
l2andl3
0
4
5
8
7
interSubFrame
0
2
0
0
0
0
0
0
0
50
10
6
4
1
channel aware
0
3
1
2
2
2560
1280ms
10
102
30
16
10
160ms
6
103
30
16
70
90
28
32
50
60
20
21
30
5
5
10
16
16
3
-103
1
-98
4
-103
18
-96
20
0
1
2
3
4
5
6
7
4
10
40ms
6
101
30
false
Not Reserved
460
29
2
100
1
nonBeamforming
2hbw
40ms
40
70
150