Как токенизировать шаблон регулярного выражения и отсортировать полученный список?

У меня есть файл, который выглядит примерно так:

select a,b,c FROM Xtable
select a,b,c FROM Vtable
select a,b,c FROM Atable
select a,b,c FROM Atable
select d,e,f FROM Atable

Я хочу получить sortedMap:

{
"Atable":["select a,b,c FROM Atable", "select d,e,f FROM Atable"],
"Vtable":["select a,b,c FROM Vtable"],
"Xtable":["select a,b,c FROM Xtable"]
}

Ключами sortedMap будут tableName, а значениями будут текстовая строка в списке.

Я начал с этого, но застрял в токенизации строки для сопоставления регулярных выражений:

import re

f = open('mytext.txt', 'r')
x = f.readlines()
print x
f.close()
for i in x:
    p = re.search(".* FROM ", i)
 //now how to tokenize and get the value that follows FROM

Вот (.*FROM[ \t]+(\S+))

user557597 31.05.2019 02:05

@sln, как мне получить токен сразу после FROM? т.е. Atable, Btable и т. д.

eagertoLearn 31.05.2019 03:35

У Python нет sortedMap, у него есть OrderedDict.

DYZ 31.05.2019 04:10

@eagertoLearn — Группа 1 = select a,b,c FROM Atable, Группа 2 = Atable, а затем сочиняйте, как вам нужно.

user557597 31.05.2019 04:19
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
4
139
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Скорее всего, мы не захотим выполнять эту задачу с помощью регулярных выражений, но если захотим, может начинаться с простого выражения, возможно, похожего на:

\"(.+?([a-z]+))\"

Мы бы заменили его на "\2":["\1"],, а затем добавили бы {}.

Тестовое задание

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

import re

regex = r"\"(.+?([a-z]+))\""

test_str = ("\"select a,b,c FROM Xtable\"\n"
    "\"select a,b,c FROM Vtable\"\n"
    "\"select a,b,c FROM Atable\"\n"
    "\"select a,b,c FROM Atable\"\n"
    "\"select d,e,f FROM Atable\"")

subst = "\"\\2\":[\"\\1\"],"

# You can manually specify the number of replacements by changing the 4th argument
result = re.sub(regex, subst, test_str, 0, re.MULTILINE | re.IGNORECASE)

if result:
    print (result)

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

регулярное выражение

Если это выражение не нужно, его можно модифицировать/изменить в regex101.com.

Цепь регулярных выражений

jex.im визуализирует регулярные выражения:

если не регулярное выражение, как еще вы хотели бы сделать тогда?

eagertoLearn 31.05.2019 03:32

и это не удается, если я удаляю двойные кавычки, например select a,b,c FROM Xtable

eagertoLearn 31.05.2019 03:40

Результатом будет строка, а не dict.

DYZ 31.05.2019 04:19
Ответ принят как подходящий

Вы можете использовать комбинацию defaultdict и регулярных выражений. Пусть lines будет списком ваших строк:

from collections import defaultdict
pattern = "(select .+ from (\S+).*)"
results = defaultdict(list)

for line in lines:
     query, table = re.findall(pattern, line.strip(), flags=re.I)[0]
     results[table].append(query)

На самом деле, правильный способ чтения файла:

with open('mytext.txt') as infile:
    for line in infile:
         query, table = re.findall(pattern, line.strip(), flags=re.I)[0]
         results[table].append(query)

Результат, естественно, defaultdict. Если вы хотите преобразовать его в упорядоченный словарь, вызовите конструктор словаря:

from collections import OrderedDict
OrderedDict(sorted(results.items()))
#OrderedDict([('Atable', ['select a,b,c FROM Atable', ...

Вы можете сделать pattern более надежным, чтобы отслеживать запятые, действительные идентификаторы и т. д.

это не похоже на отсортированный дикт?

eagertoLearn 31.05.2019 04:03

прекрасно работает. пару вещей, которые я заметил с моими тестовыми данными. существует один тип запроса, например «выбрать a, b, c из TableX, где id = 10» и «выбрать a, b (выбрать d, e из таблицы Y) из TableX». В обоих случаях я ожидаю, что «TableX» будет ключом и значением для запроса.

eagertoLearn 31.05.2019 04:13

так что в основном получите следующий токен из последнего «FROM» в операторе select. С текущим я получаю ключ как «TableX, где id = 10», что неверно.

eagertoLearn 31.05.2019 04:14

вы упомянули, что эту проблему трудно решить, и вы сделали это за минуту :). Это прекрасно работает. Сейчас я работаю над большим файлом. Я приму это, как только оно будет закончено. Спасибо еще раз

eagertoLearn 31.05.2019 04:21

Другие вопросы по теме