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