2011-05-11 1 views
1

아래의 Python 스크립트로 WURFL XML 파일에서 모든 전화 화면 해상도를 추출하려고합니다. 문제는 내가 첫 번째 경기 만 얻는다는 것이다. 왜? 내가 어떻게 모든 경기를 할 수 있니? Python 정규식 문제

WURFL XML 파일

이 특별히 findall는 각 패턴 일치에서 일치하는 첫 번째 그룹을 반환 findall의 행동에 oddness입니다 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

에서 찾을 수 있습니다. this question을 참조하십시오.

+0

명확한 설명 : 다음 다음 stdlib etree 모듈과 (IMHO) 무시 무시한 XPath의의 뿌리를 사용하는 나는 그룹이 내가 관심이 있지만 findall은 단지 몇 가지 이유 ONE 경기 (첫 번째 일치)을 반환받을. – AOO

1

먼저 정규 표현식 대신 XML 구문 분석기를 사용하십시오. 장기적으로 당신은 더 행복해질 것입니다.

두 번째로 정규 표현식 사용을 주장하는 경우 findall() 대신 finditer()을 사용하십시오.

셋째, 당신의 정규식은 마지막으로 첫 번째 항목합니다 (.* 욕심, 그리고 당신이 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

+0

죄송합니다. 수정 된 정규식으로 다시 시도하십시오. –

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 파서를 사용하여이 경우에 더 좋을 것이다.

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