-1

我正在尝试解析一些 XML,寻找标签名称为“ip”的元素最终我需要一个包含 IP 地址的字符串列表。这是我尝试过的:

def parseHosts(xmldoc):
  hostsNode = xmldoc.firstChild
  xmlList = hostsNode.getElementsByTagName("ip")

  ipList = []
  for ip in xmlList:
    ipList.append(ip.childNodes[0].nodeValue)

  print ipList
>>>[u'172.16.60.92', u'172.16.60.89', u'\n              ', u'172.16.60.90', u'172.16.60.91', u'172.16.60.93']

没关系。但我需要一个 IP 地址字符串列表...我不希望节点为空。只是一个很好的地址列表,如下所示:

['172.16.60.1', '172.16.60.5', 172.16.60.100']

我尝试了一些带有列表理解的正则表达式

  regex = re.compile(r'172\.16\.[0-9]*\.[0-9]*')
  [m.group(0) for l in ipList for m in [regex.search(1)] if m]

但我收到以下错误

File "myParser.py", line 47, in parseHosts
[m.group(0) for l in ipList for m in [regex.search(1)] if m]
TypeError: expected string or buffer

并尝试我可能无法找到 ipList 正在使用的类型,type(ipList)也无法弄清楚如何使这些东西成为字符串。

另外......摆脱那些Unicode的东西会很好。

很明显,我已经走到了某个地方的深处,但我不知道该去哪里找。

4

2 回答 2

3

让我们回到您的原始代码。它最终在ipList

[u'172.16.60.92', u'172.16.60.89', u'\n              ', u'172.16.60.90', u'172.16.60.91', u'172.16.60.93']

这里唯一的问题是它包含充满空格的字符串,以及带有 IP 地址的字符串,对吧?

所以,让我们在事后过滤它:

In [51]: ipList = [u'172.16.60.92', u'172.16.60.89', u'\n              ', u'172.16.60.90', u'172.16.60.91', u'172.16.60.93']

In [52]: ipList = [ip for ip in ipList if ip.strip()]

In [53]: ipList
Out[53]: 
['172.16.60.92',
 '172.16.60.89',
 '172.16.60.90',
 '172.16.60.91',
 '172.16.60.93']

你完成了!

为什么这行得通?好吧,ip.strip()将从左侧和右侧删除所有空格。将结果粘贴到if语句中,如果有任何剩余,则为真,如果没有任何剩余,则为假。

但显然,您可以将相同的条件移回原始循环,将其放在append调用之前,效果完全相同:

def parseHosts(xmldoc):
  hostsNode = xmldoc.firstChild
  xmlList = hostsNode.getElementsByTagName("ip")

  ipList = []
  for ip in xmlList:
    ipstr = ip.childNodes[0].nodeValue
    if ipstr.strip():
      ipList.append(ipstr)

但是整个ipList部分显然只是列表理解的冗长版本,所以:

def parseHosts(xmldoc):
  hostsNode = xmldoc.firstChild
  xmlList = hostsNode.getElementsByTagName("ip")
  ipList = [ip.childNodes[0].nodeValue for ip in xmlList
            if ip.childNodes[0].nodeValue.strip()]

至于您尝试解决此问题:

[m.group(0) for l in ipList for m in [regex.search(1)] if m]

每当嵌套列表推导的作用不是很明显时,将其分成两个推导。

但是让我们将其重写为显式循环。这不仅使它更容易理解,而且使调试更容易:

result = []
for l in ipList:
    for m in [regex.search(1)]:
        if m:
            result.append(m.group(0))

当你运行它时,你会在第三行得到一个异常,原因应该很明显。

于 2013-01-08T22:48:20.107 回答
0

你可以使用filter(regex.match,ipList)

import re
ipList=[u'172.16.60.92', u'172.16.60.89', u'\n              ', u'172.16.60.90', u'172.16.60.91', u'172.16.60.93']
regex = re.compile(r'172\.16\.[0-9]*\.[0-9]*')
filter(regex.match,ipList)

out:

[u'172.16.60.92',
 u'172.16.60.89',
 u'172.16.60.90',
 u'172.16.60.91',
 u'172.16.60.93']
于 2013-01-08T22:56:54.313 回答