建议python正则表达式和选择列

时间:2014-04-24 13:51:34

标签: python regex parsing python-2.7

如何在一个由空格分隔的3列,4列或X列的文件中选择(不是常量空格,而是每行多个空格),用正则表达式选择每行的前2列?

我的文件包括:IP [SPACES] Subnet_Mask [SPACES] NEXT_HOP_IP [NEW LINE]

所有行都使用该格式。如何仅提取前两列? (IP和子网掩码)

以下是尝试使用正则表达式的示例:

10.97.96.0 10.97.97.128 47.73.1.0
47.73.4.128 47.73.7.6 47.73.8.0
47.73.15.0   47.73.40.0   47.73.41.0
85.205.9.164 85.205.14.44 172.17.103.0
172.17.103.8 172.17.103.48 172.17.103.56
172.17.103.96         172.17.103.100       172.17.103.136
172.17.103.140 172.17.104.44            172.17.105.28
172.17.105.32       172.17.105.220      172.17.105.224

不要查看特定的IP。我知道第二列不是由有效的地址掩码组成的。这只是一个例子。

我已经尝试过:

(?P<IP_ADD>\s*[1-9][0-9]{1,2}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})(?P<space>\s*)(?P<MASK>[1-9][0-9]{1,2}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}(\s+|\D*))

但它不太有用......

4 个答案:

答案 0 :(得分:1)

一个班轮是:

[s.split()[:2] for s in string.split('\n')]

示例

string = """10.97.96.0 10.97.97.128 47.73.1.0
47.73.4.128 47.73.7.6 47.73.8.0
47.73.15.0   47.73.40.0   47.73.41.0
85.205.9.164 85.205.14.44 172.17.103.0
172.17.103.8 172.17.103.48 172.17.103.56
172.17.103.96         172.17.103.100       172.17.103.136
172.17.103.140 172.17.104.44            172.17.105.28
172.17.105.32       172.17.105.220      172.17.105.224"""

print [s.split()[:2] for s in string.split('\n')]

输出

[['10.97.96.0', '10.97.97.128']
['47.73.4.128', '47.73.7.6']
['47.73.15.0', '47.73.40.0']
['85.205.9.164', '85.205.14.44']
['172.17.103.8', '172.17.103.48']
['172.17.103.96', '172.17.103.100']
['172.17.103.140', '172.17.104.44']
['172.17.105.32', '172.17.105.220']]

答案 1 :(得分:1)

使用正则表达式:

如果你想获得2个第一列,无论它们包含什么,以及分隔它们的空间大小,你可以使用\S(匹配除空格之外的任何内容)和\s(仅匹配空格)实现这一点:

import re
lines = """
    47.73.4.128 47.73.7.6 47.73.8.0
    47.73.15.0   47.73.40.0   47.73.41.0
    85.205.9.164 85.205.14.44 172.17.103.0
    172.17.103.8 172.17.103.48 172.17.103.56
    172.17.103.96         172.17.103.100       172.17.103.136
    172.17.103.140 172.17.104.44            172.17.105.28
    172.17.105.32       172.17.105.220      172.17.105.224
"""
regex = re.compile(r'(\S+)\s+(\S+)')
regex.findall(lines)

结果:

[('10.97.96.0', '10.97.97.128'),
 ('47.73.1.0', '47.73.4.128'),
 ('47.73.7.6', '47.73.8.0'),
 ('47.73.15.0', '47.73.40.0'),
 ('47.73.41.0', '85.205.9.164'),
 ('85.205.14.44', '172.17.103.0'),
 ('172.17.103.8', '172.17.103.48'),
 ('172.17.103.56', '172.17.103.96'),
 ('172.17.103.100', '172.17.103.136'),
 ('172.17.103.140', '172.17.104.44'),
 ('172.17.105.28', '172.17.105.32'),
 ('172.17.105.220', '172.17.105.224')]

没有正则表达式

如果您不想使用正则表达式,并且仍然能够处理多个空格,您还可以这样做:

while '  ' in lines:  # notice the two-spaces-string
    lines = lines.replace('  ', ' ')
columns = [line.split(' ')[:2] for line in lines.split('\n') if line]

利弊:

使用正则表达式的优点是,如果分隔符包含表格,它也会正确解析数据,而第二种解决方案则不然。 另一方面,正则表达式需要比简单的字符串拆分更多的计算,这可能会对非常大的数据集产生影响。

答案 2 :(得分:0)

编辑以与任意数量的空格进行空间匹配。

如果您知道它将成为前2个空格分隔值,则可以使用此python regular expressions作为选项完成此操作。

一个不错的regex cheat sheet也可以帮助您找到一些快捷方式。特定的标记类,如单词,空格和数字,都有这些小捷径。

import re
line = "10.97.96.0 10.97.97.128 47.73.1.0"
result = re.split("\s+", line)[0:2]

result
['10.97.96.0', '10.97.97.128']

答案 3 :(得分:0)

因为你需要“某种单行”,所以有很多方法都不涉及python。 也许:

| awk '{print $1,$2}'

包含任何在stdout上产生输入的内容。