2008-12-06 3 views
3

У меня есть строка, как это, что мне нужно, чтобы разобрать на 2D массива:Python регулярное выражение

str = "'813702104[813702106]','813702141[813702143]','813702172[813702174]'" 

эквив массив будет:

arr[0][0] = 813702104 
arr[0][1] = 813702106 
arr[1][0] = 813702141 
arr[1][1] = 813702143 
#... etc ... 

Я пытаюсь сделать это с помощью Regex , Строка выше похожа на HTML-страницу, но я могу быть уверен, что это единственная строка в этом шаблоне на странице. Я не уверен, что это лучший способ, но это все, что у меня есть прямо сейчас.

imgRegex = re.compile(r"(?:'(?P<main>\d+)\[(?P<thumb>\d+)\]',?)+") 

Если я бегу imgRegex.match(str).groups() я получаю только один результат (первый куплет). Как я могу получить несколько совпадений назад или объект соответствия 2d (если такая вещь существует!)?

Примечание: Вопреки тому, как это может выглядеть, это не домашнее задание

Примечание часть ДЕЗ: Реальная строка встраивается в большой HTML файл и, следовательно, расщепление не представляется быть вариантом.

Я по-прежнему получаю ответы на это, поэтому я решил изменить его, чтобы показать, почему я не изменяю принятый ответ. Разделение, хотя и более эффективное в этой тестовой строке, не собирается извлекать детали из целого HTML-файла. I может объединить регулярное выражение и расщепление, но это кажется глупым.

Если у вас есть лучший способ найти детали из загрузки HTML (шаблон \d+\[\d+\] уникален для этой строки в источнике), я с радостью изменю принятые ответы. Все остальное - академическое.

+0

Я добавил, что я думаю, что arr [1] [0] и arr [1] [1] должны выглядеть, потому что это было не совсем ясно. но я не знаю ни одного python, поэтому я не могу помочь вам с вашим вопросом. – Kip 2008-12-06 13:37:34

+0

Да, у меня было [2] [*] изначально тоже, но я не был уверен, что это просто отрывает сообщение, но я вижу вашу точку , Спасибо за ваше редактирование. – Oli 2008-12-06 13:39:15

+0

Предполагаете, что вы имели в виду: str = "'813702104 [' 813702106] ',' 813702143] ',' 813702172 [813702174] '" – 2008-12-06 13:41:13

ответ

5

Я бы попробовал findall или finditer вместо match.

Редактируйте Оли: Да findall работа блестяще, но я должен был упростить регулярное выражение:

r"'(?P<main>\d+)\[(?P<thumb>\d+)\]',?" 
1

Внесение изменений в регулярное выражение немного,

>>> str = "'813702104[813702106]','813702141[813702143]','813702172[813702174]" 
>>> imgRegex = re.compile(r"'(?P<main>\d+)\[(?P<thumb>\d+)\]',?") 
>>> print imgRegex.findall(str) 
[('813702104', '813702106'), ('813702141', '813702143')] 

Который является «2 одномерный массив» - в Python, «список из 2-х кортежей».

1

У меня есть кое-что, кажется, работает на наборе данных:

In [19]: str = "'813702104[813702106]','813702141[813702143]','813702172[813702174]'" 
In [20]: ptr = re.compile(r"'(?P<one>\d+)\[(?P<two>\d+)\]'") 
In [21]: ptr.findall(str) 
Out [23]: 
[('813702104', '813702106'), 
('813702141', '813702143'), 
('813702172', '813702174')] 
3

Я думаю, что не будет идти на регулярное выражение для решения этой задачи. Список Python понимание является достаточно мощным для этого

In [27]: s = "'813702104[813702106]','813702141[813702143]','813702172[813702174]'" 

In [28]: d=[[int(each1.strip(']\'')) for each1 in each.split('[')] for each in s.split(',')] 

In [29]: d[0][1] 
Out[29]: 813702106 

In [30]: d[1][0] 
Out[30]: 813702141 

In [31]: d 
Out[31]: [[813702104, 813702106], [813702141, 813702143], [813702172, 813702174]] 
1

В качестве альтернативы, вы можете использовать [заявления для пункта в списке] Питон синтаксис для создания списков. Вы должны найти это намного быстрее, чем регулярное выражение, особенно для небольших наборов данных. Большие наборы данных будут показывать менее выраженную разницу (нужно только загрузить механизм регулярных выражений, независимо от размера), но listmaker всегда должен быть быстрее.

Start, разбивая строку на запятых:

>>> str = "'813702104[813702106]','813702141[813702143]','813702172[813702174]'" 
>>> arr = [pair for pair in str.split(",")] 
>>> arr 
["'813702104[813702106]'", "'813702141[813702143]'", "'813702172[813702174]'"] 

Прямо сейчас, это возвращает то же самое, только str.split («»), так что это не очень полезно, но вы должны быть в состоянии чтобы увидеть, как работает listmaker - он выполняет итерацию по списку, присваивая каждое значение элементу, выполняя инструкцию и добавляя полученное значение к вновь созданному списку.

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

>>> arr = [pair[1:-2].split("[") for pair in str.split(",")] 
>>> arr 
>>> [['813702104', '813702106'], ['813702141', '813702143'], ['813702172', '813702174']] 

Это возвращает двумерный массив, как вы описываете, но все элементы представляют собой целые строки, а не целые числа. Если вы просто собираетесь использовать их как строки, это достаточно далеко. Если вам нужно, чтобы они были действительные целые числа, вы просто использовать «внутренний» ListMaker как утверждение для «внешнего» ListMaker:

>>> arr = [[int(x) for x in pair[1:-2].split("[")] for pair in str.split(",")] 
>>> arr 
>>> [[813702104, 813702106], [813702141, 813702143], [813702172, 813702174]] 

Это возвращает двумерный массив целых чисел, представляющий в строке Понравился один, который вы предоставили, без необходимости загрузки механизма регулярных выражений.

Смежные вопросы