1

我正在尝试使用以下 Python 脚本从 WURFL XML 文件中提取所有手机屏幕分辨率。但问题是我只得到了第一场比赛。为什么?我怎么能得到所有的比赛?

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)
4

4 回答 4

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会在“正常”字符串中出现意外行为。

于 2011-05-11T11:29:38.880 回答
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
于 2011-05-11T11:38:13.643 回答
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
于 2011-05-11T12:39:48.877 回答
0

这是 的行为的一个奇怪之处findall,特别是findall只返回每个模式匹配的第一个匹配组。看到这个问题

于 2011-05-11T11:10:41.540 回答