将正则表达式的结果组合成x,y对

时间:2014-12-12 22:17:09

标签: python regex geospatial

我试图从我的数据库中获取字符串输出,在字符串上运行正则表达式,然后结合正则表达式中的一些结果。我需要将多个结果放在一起以创建一个简洁的csv输出,我可以将其拉入R.(我真正感到困惑的是将单个结果存储为正则表达式中的单独变量 - 这是更大的事情我无法弄清楚。无论如何......)

这是我试图清理的字符串示例。

LINESTRING (-1 -2, -2 3.8, -1 5.6, 0 -3, 1.5 3.3, 2 -23, 6 -12)

我希望输出看起来像这样:

x,y
-1,-2
-2,3.8
-1,5.6
0,-3
1.5,3.3
2,-23
6,-12

奖励,如果我们可以使它看起来像这样(R中的段功能的最佳方式):

x1,y1,x2,y2
-1,-2,-2,3.8
-2,3.8,-1,5.6
-1,5.6,0,-3
0,-3,1.5,3.3
1.5,3.3,2,-23
2,-23,6,-12
6,-12,6,-12

这是我的代码:

import re

file_name = 'linestring.dat'

lines = open(file_name)
data = lines.read()
print("x, y")
regex = re.compile("([-+]?\d*\.\d+|[-+]?\d+)")
clean_data = regex.findall(data)
for line in clean_data:
    print line

分别打印每个正则表达式结果。我不知道如何迭代结果并将每个结果分配给变量以生成我可以打印的x,y对。

感谢您的帮助,我希望我的问题对其他R和Python人员有所帮助。

6 个答案:

答案 0 :(得分:1)

第一个解决方案:

>>> >>> my_string = "-1 -2, -2 3.8, -1 5.6, 0 -3, 1.5 3.3, 2 -23, 6 -12"
>>> my_list = map(str.split,my_string.split(', '))
>>> my_list
[['-1', '-2'], ['-2', '3.8'], ['-1', '5.6'], ['0', '-3'], ['1.5', '3.3'], ['2', '-23'], ['6', '-12']]

如果你加入\ n并打印出来,它会看起来像你期望的那样:

>>> print("\n".join(map(",".join,my_list)))
-1,-2
-2,3.8
-1,5.6
0,-3
1.5,3.3
2,-23
6,-12

第二个解决方案:

>>> my_list
[['-1', '-2'], ['-2', '3.8'], ['-1', '5.6'], ['0', '-3'], ['1.5', '3.3'], ['2', '-23'], ['6', '-12']]
>>> for i in range(len(my_list)):
...     if i == len(my_list)-1:
...         print(",".join(my_list[i]+my_list[i]))
...     else:print(",".join(my_list[i]+my_list[i+1]))
... 
-1,-2,-2,3.8
-2,3.8,-1,5.6
-1,5.6,0,-3
0,-3,1.5,3.3
1.5,3.3,2,-23
2,-23,6,-12
6,-12,6,-12

答案 1 :(得分:0)

使用正则表达式,您可以使用zip来获取第一个表单:

>>> for x1,y1 in zip(clean_data[::2],clean_data[1::2]):
...   print ",".join([x1,y1])
... 
-1,-2
-2,3.8
-1,5.6
0,-3
1.5,3.3
2,-23
6,-12

而对于第二个(我担心这不是非常pythonic,但也不高效):

>>> for x1,y1,x2,y2 in zip(clean_data[::2],clean_data[1::2],clean_data[2::2],clean_data[3::2]):
...  print ",".join([x1,y1,x2,y2])
... 
-1,-2,-2,3.8
-2,3.8,-1,5.6
-1,5.6,0,-3
0,-3,1.5,3.3
1.5,3.3,2,-23
2,-23,6,-12

答案 2 :(得分:0)

如果clean_data看起来像这样:

['-1', '-2', '-2', '3.8', '-1', '5.6', '0', '-3', '1.5', '3.3', '2', '-23', '6', '-12']

为了成对加入元素,我们可以执行以下操作:

l = zip(clean_data[0::2], clean_data[1::2])

这意味着将奇数索引元素与相应的偶数元素配对。现在您可以将它们打印出来或做进一步的处理:例如:

>>> for i in l:
    print(i)


('-1', '-2')
('-2', '3.8')
('-1', '5.6')
('0', '-3')
('1.5', '3.3')
('2', '-23')
('6', '-12')

答案 3 :(得分:0)

这可以不用重做,例如,如果这是你的字符串:

l = "LINESTRING (-1 -2, -2 3.8, -1 5.6, 0 -3, 1.5 3.3, 2 -23, 6 -12)"

从括号之间抓取数字并将它们作为字符串对放入列表中,然后遍历它们以获取输出,用逗号替换空格

data = l.split('(', 1)[1].split(')')[0].split(',')
for d in data:
    print d.strip().replace(' ',',')

为了获得R的最佳方式,您可以利用该列表中的索引号:

for k,d in enumerate(data):
    first = data[k].strip().replace(' ',',').strip()
    try:
        second = data[k+1].strip().replace(' ',',')
    except IndexError:
        # this is the last line, use the first value as second (maybe?)
        second = first
    print "%s,%s" % (first, second)

答案 4 :(得分:0)

在R

x <- "-1 -2, -2 3.8, -1 5.6, 0 -3, 1.5 3.3, 2 -23, 6 -12"

xx <- Filter(Negate(is.na), as.numeric(strsplit(x, "[\\s+|,]", perl = TRUE)[[1]]))

do.call('rbind', lapply(seq(1, length(xx) - 2, by = 2),
                        function(ii) xx[ii:(ii + 3)]))

#      [,1]  [,2] [,3]  [,4]
# [1,] -1.0  -2.0 -2.0   3.8
# [2,] -2.0   3.8 -1.0   5.6
# [3,] -1.0   5.6  0.0  -3.0
# [4,]  0.0  -3.0  1.5   3.3
# [5,]  1.5   3.3  2.0 -23.0
# [6,]  2.0 -23.0  6.0 -12.0

答案 5 :(得分:0)

如果由于某种原因需要使用正则表达式,请尝试以下操作:

import re
s = r'LINESTRING (-1 -2, -2 3.8, -1 5.6, 0 -3, 1.5 3.3, 2 -23, 6 -12)'

numeric = re.findall(r'LINESTRING \(([^\)]+)', s)
numbers = list(re.findall(r'([.+\-\d]+)', numeric[0]))

for i in range(0,len(numbers),2):
    ns = numbers[i:i+4]
    if len(ns) == 2: ns *= 2
    print(tuple(map(float, ns)))

'''
(-1.0, -2.0, -2.0, 3.8)
(-2.0, 3.8, -1.0, 5.6)
(-1.0, 5.6, 0.0, -3.0)
(0.0, -3.0, 1.5, 3.3)
(1.5, 3.3, 2.0, -23.0)
(2.0, -23.0, 6.0, -12.0)
(6.0, -12.0, 6.0, -12.0)
'''