Вопрос:

Регулярные выражения, возвращающие частичные совпадения

python python-3.5

24 просмотра

3 ответа

319 Репутация автора

У меня есть файл kml со списком мест назначения вместе с координатами. В этом файле около 40+ направлений. Я пытаюсь разобрать координаты из него, когда вы смотрите в файле, вы видите "координаты" ... "/ координаты", поэтому их поиск не будет трудной частью, но я не вижу, чтобы получить полный результат , Что я имею в виду, это будет вырезать -94. или любой отрицательный плавающий с самого начала, и напечатайте остальную часть.

#!/usr/bin/python3.5

import re

def main():

    results = []
    with open("file.kml","r") as f:
        contents = f.readlines()

    if f.mode == 'r':
        print("reading file...")
        for line in contents:
            coords_match = re.search(r"(<coordinates>)[+-]?\d+\.\d+|\d+\,\-?\d+\.\d+|\d+(?=</coordinates)",line)
            if coords_match:
                coords_matchh = coords_match.group()
                print(coords_matchh)

вот некоторые из результатов, которые я получаю

3502969,38.8555497
7662462,38.8583916
6280323,38.8866337
3655059,39.3983001

Вот как формат в файле, если это имеет значение

<coordinates>
  -94.5944738,39.031411,0
</coordinates>

Если я изменю эту строку и уберу координаты с начала

coords_match = re.search(r"[+-]?\d+\.\d+|\d+\,\-?\d+\.\d+|\d+(?=</coordinates)",line)

это результаты, которые я получаю вместо этого.

-94.7662462
-94.6280323
-94.3655059

Это по сути желаемый результат, который я хочу.

-94.7662462,38.8583916
-94.6280323,38.8866337
-94.3655059,39.3983001

Автор: andyADD Источник Размещён: 11.08.2019 07:15

Ответы (3)


0 плюса

1170 Репутация автора

В то время как использование фактического парсера - путь, как @Kendas предложил в комментариях, вы можете попробовать findallвместоsearch

>>> import re
>>> s = """<coordinates>
...   -94.5944738,39.031411,0
... </coordinates>"""
>>> re.findall(r'[+-]?\d+\.\d+|\d+\,\-?\d+\.\d+|\d+(?=</coordinates)', s)
['-94.5944738', '39.031411']
Автор: political scientist Размещён: 11.08.2019 07:23

0 плюса

3982 Репутация автора

Вы также можете использовать BeauitfulSoup для получения координат, так как это будет XML / HTML-анализ.

from bs4 import BeautifulSoup

text = """<coordinates>
              -94.5944738,39.031411,0
            </coordinates>
            <coordinates>
              -94.59434738,39.032311,0
            </coordinates>
            <coordinates>
              -94.523444738,39.0342411,0
            </coordinates>"""
soup = BeautifulSoup(text, "lxml")
coordinates = soup.findAll('coordinates')

for i in range(len(coordinates)):
    print(coordinates[i].text.strip()[:-2])

Выход:

-94.5944738,39.031411
-94.59434738,39.032311
-94.523444738,39.0342411
Автор: Ankur Sinha Размещён: 11.08.2019 07:54

0 плюса

28109 Репутация автора

Синтаксический анализатор XML является излишним, если вы просто хотите извлечь простые данные с разделителями.

Главное - использовать более простое регулярное выражение и выполнять поиск по всему файлу. Сосредоточьтесь на захвате всего между тегами:

with open("file.kml","r") as f:
    contents = f.read()
coords_match = re.findall(r'<coordinates>(.*?)</coordinates>', contents, re.DOTALL)

Это вернет список совпадений. Каждый элемент в этом списке будет выглядеть примерно так:

'\n  -94.5944738,39.031411,0\n  '

Итак, для каждого предмета вам необходимо:

  1. убрать пробел
  2. правое разделение на последний ","
  3. откажитесь от второго результата.

Итак, вы делаете это:

results = [c.strip().rsplit(',', 1)[0] for c in coords_match]

Это дает вам список желаемых строк.

Если вы действительно хотите использовать числа, я бы преобразовал числа в числа с плавающей запятой (используя вложенное понимание):

results = [tuple(float(f) for f in  c.strip().split(',')[:2]) for c in coords_match]

Это даст вам список из 2-х кортежей float.

Демонстрация в IPython:

In [1]: import re                                                                                        

In [2]: text = """<coordinates> 
   ...:               -94.5944738,39.031411,0 
   ...:             </coordinates> 
   ...:             <coordinates> 
   ...:               -94.59434738,39.032311,0 
   ...:             </coordinates> 
   ...:             <coordinates> 
   ...:               -94.523444738,39.0342411,0 
   ...:             </coordinates>"""                                                                    

In [3]: coords_match = re.findall(r'<coordinates>(.*?)</coordinates>', text, re.DOTALL)                  
Out[3]: 
['\n              -94.5944738,39.031411,0\n            ',
 '\n              -94.59434738,39.032311,0\n            ',
 '\n              -94.523444738,39.0342411,0\n            ']

In [4]: results1 = [c.strip().rsplit(',', 1)[0] for c in coords_match]                                   
Out[4]: ['-94.5944738,39.031411', '-94.59434738,39.032311', '-94.523444738,39.0342411']

In [5]: results2 = [tuple(float(f) for f in  c.strip().split(',')[:2]) for c in coords_match]            
Out[5]: 
[(-94.5944738, 39.031411),
 (-94.59434738, 39.032311),
 (-94.523444738, 39.0342411)]
Автор: Roland Smith Размещён: 11.08.2019 07:54
Вопросы из категории :
32x32