2011-05-11 61 views
1

我想用下面的Python脚本从WURFL XML文件中提取所有手机屏幕分辨率。问题是,我只获得第一场比赛。为什么?我怎么能得到所有比赛?Python的正则表达式问题

的WURFL XML文件可以在http://sourceforge.net/projects/wurfl/files/WURFL/latest/wurfl-latest.zip/download?use_mirror=freefr

def read_file(file_name): 
    f = open(file_name, 'rb') 
    data = f.read() 
    f.close() 
    return data 

text = read_file('wurfl.xml') 

import re 
pattern = '<device id="(.*?)".*actual_device_root="true">.*<capability name="resolution_width" value="(\d+)"/>.*<capability name="resolution_height" value="(\d+)"/>.*</device>' 
for m in re.findall(pattern, text, re.DOTALL): 
    print(m) 

回答

0

中找到这在findall行为的奇怪,特别findall只从各图案匹配返回第一个匹配组。见this question

+0

澄清:我拿到团体我很感兴趣,但只的FindAll返回ONE出于某种原因比赛(第一场比赛)。 – AOO 2011-05-11 11:23:53

1

首先,使用XML解析器而不是正则表达式。长远来看,你会更开心。

其次,如果您坚持使用正则表达式,请使用finditer()而不是findall()

三,你的正则表达式从第一项到最后一个(在.*是贪婪的,并且已经设置DOTALL模式)相匹配,所以无论是看到的第一款或者至少你的正则表达式改为

pattern = r'<device id="(.*?)".*?actual_device_root="true">.*?<capability name="resolution_width" value="(\d+)"/>.*?<capability name="resolution_height" value="(\d+)"/>.*?</device>' 

另外,总是使用原始字符串和正则表达式。但是,\d恰好工作,\b将在“正常”字符串中表现出意外。

+0

感谢您的输入,但我仍然只获得一场比赛 – AOO 2011-05-11 11:37:12

+0

哎呀,我忽略了一个贪婪的量词。请使用编辑后的正则表达式重试。 – 2011-05-11 12:12:54

0

您正在使用“贪婪”匹配:.*将匹配尽可能多的文本,这意味着<capabilities>之前的.*匹配大部分文件。

text = open('wurfl.xml').read() 
pattern = r'<device id="(.*?)".*?actual_device_root="true">.*?<capability name="resolution_width" value="(\d+)"/>.*?<capability name="resolution_height" value="(\d+)"/>.*?</device>' 
for m in re.findall(pattern, text, re.DOTALL): 
    print m 
0

我当然不反对用正则表达式处理XML,如果要求很简单,但也许在这种情况下使用真正的XML解析器会更好。使用STDLIB etree模块的(恕我直言)可怕的XPath洒:

import xml.etree.ElementTree as ET 

def capability_value(cap_elem): 
    if cap_elem is None: 
     return None 
    return int(cap_elem.attrib.get('value')) 

def devices(wurfl_doc): 
    for el in wurfl_doc.findall("/devices/device[@actual_device_root='true']"): 
     width = el.find("./group[@id='display']/capability[@name='resolution_width']") 
     width = capability_value(width) 
     height = el.find("./group[@id='display']/capability[@name='resolution_height']") 
     height = capability_value(height) 
     device = { 
      'id' : el.attrib.get('id'), 
      'resolution' : {'width': width, 'height': height} 
     } 
     yield device 

doc = ET.ElementTree(file='wurfl.xml') 
for device in devices(doc): 
    print device