Регулярное выражение для захвата цифр в строке (Python)

Я новичок в python и обрабатываю текстовый файл с регулярными выражениями для извлечения идентификаторов и добавления списка. Я написал некоторый python ниже, намереваясь создать список, который выглядит следующим образом:

["10073710","10074302","10079203","10082213"...and so on]

Вместо этого я вижу структуру списка, в которую включено множество подробных тегов. Я предполагаю, что это нормальное поведение, и функция finditer добавляет эти теги, когда находит совпадения. Но ответ немного беспорядочный, и я не знаю, как отключить/удалить эти добавленные теги. Смотрите скриншот ниже.

введите здесь описание изображения

Может ли кто-нибудь помочь мне изменить приведенный ниже код, чтобы я мог получить предполагаемую структуру списка?

import re

#create a list of strings
company_id = []

#open file contents into a variable
company_data = open(r'C:\Users\etherealessence\Desktop\company_data_test.json', 'r', encoding="utf-8")

#read the line structure into a variable
line_list = company_data.readlines()

#stringify the contents so regex operations can be performed
line_list = str(line_list)

#close the file
company_data.close()

#assign the regex pattern to a variable
pattern = re.compile(r'"id":([^,]+)')

#find all instances of the pattern and append the list
#https://stackoverflow.com/questions/12870178/looping-through-python-regex-matches
for id in re.finditer(pattern, line_list): 
  #print(id)
  company_id.append(id)

#test view the list of company id strings
#print(line_list)
print(company_id)

person emalcolmb    schedule 12.05.2019    source источник
comment
Regex - ужасное решение здесь. Вы, вероятно, хотите, чтобы что-то вроде JSON Path запрашивало структуру напрямую.   -  person jpmc26    schedule 28.05.2019


Ответы (3)


re.finditer возвращает iterator из re.Match объектов.

Если вы хотите извлечь фактическое совпадение (а точнее, захваченную группу, чтобы избавиться от ведущего "id":), вы можете сделать что-то вроде этого:

for match in re.finditer(pattern, line_list):
    company_id.append(match.group(1))
person Matias Cicero    schedule 12.05.2019

Если ваши данные находятся в формате JSON, вы можете просто проанализировать их.


Если вы хотите использовать регулярное выражение, вы можете упростить свое выражение и использовать три группы захвата для желаемого идентификатора намного проще. Вы можете установить две группы захвата слева и справа от ваших идентификаторов, тогда средняя группа захвата поможет вам получить идентификаторы, возможно, что-то вроде это выражение:

("id":")([0-9]+)(") 

введите здесь описание изображения

Описательная диаграмма регулярных выражений

Эта ссылка поможет вам визуализирует ваши выражения:

введите здесь описание изображения

Тестирование Python

# coding=utf8
# the above tag defines encoding for this document and is for Python 2.x compatibility

import re

regex = r"(\x22id\x22:\x22)([0-9]+)(\x22)"

test_str = "some other JSON data'\"id\":\"10480132\"'>some other JSON datasome other JSON data'\"id\":\"10480132\"'>some other JSON datasome other JSON data'\"id\":\"10480132\"'>some other JSON datasome other JSON data'\"id\":\"10480132\"'>some other JSON datasome other JSON data'\"id\":\"10480132\"'>some other JSON data"

matches = re.finditer(regex, test_str, re.MULTILINE)

for matchNum, match in enumerate(matches, start=1):

    print ("Match {matchNum} was found at {start}-{end}: {match}".format(matchNum = matchNum, start = match.start(), end = match.end(), match = match.group()))

    for groupNum in range(0, len(match.groups())):
        groupNum = groupNum + 1

        print ("Group {groupNum} found at {start}-{end}: {group}".format(groupNum = groupNum, start = match.start(groupNum), end = match.end(groupNum), group = match.group(groupNum)))

# Note: for Python 2.7 compatibility, use ur"" to prefix the regex and u"" to prefix the test string and substitution.

Тест Python

# -*- coding: UTF-8 -*-
import re

string = "some other JSON data'\"id\":\"10480132\"'>some other JSON datasome other JSON data'\"id\":\"10480132\"'>some other JSON datasome other JSON data'\"id\":\"10480132\"'>some other JSON datasome other JSON data'\"id\":\"10480132\"'>some other JSON datasome other JSON data'\"id\":\"10480132\"'>some other JSON data"
expression = r'(\x22id\x22:\x22)([0-9]+)(\x22)'
match = re.search(expression, string)
if match:
    print("YAAAY! \"" + match.group(2) + "\" is a match ???????????? ")
else: 
    print('???? Sorry! No matches!')

Выход:

YAAAY! "10480132" is a match ????????????
person Emma    schedule 12.05.2019

Чтобы получить значение, используйте id.string:

for id in re.finditer(pattern, line_list): 
  company_id.append(id.string)

когда вы читаете только идентификатор, вы не получаете фактическое значение.

person dmitryro    schedule 12.05.2019