Regex для этой строки? Python - PullRequest
2 голосов
/ 28 апреля 2020

Для этой строки:

London:Jan 48.0,Feb 38.9,Mar 39.9,Apr 42.2,May 47.3,Jun 52.1,Jul 59.5,Aug 57.2,Sep 55.4,Oct 62.0,Nov 59.0,Dec 52.9

Я хотел бы найти все эти числа. (И только цифры)

Я пробую вот эти:

re.findall('\s(.*),', string)
re.findall(' (.*),', string)
re.findall('\s++.+,', string)
re.findall('\s{2}.{1},', string)

Но, похоже, ничего не работает.

Ответы [ 4 ]

1 голос
/ 28 апреля 2020

Использование:

import re

str = 'London:Jan 48.0,Feb 38.9,Mar 39.9,Apr 42.2,May 47.3,Jun 52.1,Jul 59.5,Aug 57.2,Sep 55.4,Oct 62.0,Nov 59.0,Dec 52.9'
num_arr = re.findall(r'\d+(?:\.\d+)?', str)
print num_arr

Вывод:

['48.0', '38.9', '39.9', '42.2', '47.3', '52.1', '59.5', '57.2', '55.4', '62.0', '59.0', '52.9']

Демонстрация и объяснение

1 голос
/ 28 апреля 2020

Поскольку у вас нет случайных периодов, любая подстрока, представляющая собой комбинацию цифр и десятичных точек, подойдет:

>>> re.findall(r'[\d.]+', nums)
['48.0', '38.9', '39.9', '42.2', '47.3', '52.1', '59.5', '57.2', '55.4', '62.0', '59.0', '52.9']

Если под «всеми этими числами» вы подразумевали только целые числа (т.е. периоды являются разделителями, а не десятичными точками), это проще:

>>> re.findall(r'\d+', nums)
['48', '0', '38', '9', '39', '9', '42', '2', '47', '3', '52', '1', '59', '5', '57', '2', '55', '4', '62', '0', '59', '0', '52', '9']
1 голос
/ 28 апреля 2020

Давайте рассмотрим четыре ваших начальных шаблона и рассмотрим их синтаксис, а затем рассмотрим несколько выражений, соответствующих строке, которой вы хотите соответствовать (ie 00.0).

Просмотр шаблонов

re.findall('\s(.*),', string)

Этот шаблон гласит: Найти все один символ пробела (\ s), 0 или более повторений любого символа, кроме новой строки (. * ), и запятая (,).

Этот шаблон, скорее всего, будет соответствовать всей строке, поскольку квалификаторы повторения жадные (т. Е. Любой из символов выражения + * ? будет продолжать совпадать с любым символом, который возвращает совпадение с предыдущим символом выражения. Когда мы используем '. *' в выражении, он почти всегда будет захватывать всю строку, потому что он будет жадно совпадать со всеми символами, не являющимися символом новой строки.

re.findall(' (.*),', string)

Та же проблема, что и в предыдущем шаблоне.

re.findall('\s++.+,', string)

Я не думаю, что Python re принимает квалификаторы повторения, ссылающиеся на другой квалификатор повторения без escape-кода г это. Использование «++» завершится неудачно, если только перед первым «+» не стоит символ «\»: «++». Однако это выражение выглядит так: Соответствует одному или нескольким символам «+» ('++). Часть выражения '. +' соответствует одному или нескольким повторениям любого символа, который не является новой строкой ('. +') И становится жертвой жадной проблемы.

re.findall('\s{2}.{1},', string)

Squiggly скобки являются квалификаторами повторения, которые позволяют вводить диапазон повторений. Они следуют синтаксису '{m, n}', где m - наименьшее количество совпадений, а n - наибольшее. Например, шаблон AB{3, 4} не будет соответствовать ABB, но он будет соответствовать ABBB или ABBBB.

Шаблон выше выглядит так: 2 повторения любого символа пробела ('\ s {2}'), за которым следует любой символ, не являющийся символом новой строки ('. {1}'), за которым следует запятая.

Здесь Есть пара различных шаблонов, чтобы попробовать - я также коснусь синтаксиса.

import re

p = ‘[0-9][0-9]\.[0-9]’
s = ‘ London:Jan 48.0,Feb 38.9,Mar 39.9,Apr 42.2,May 47.3,Jun 52.1,Jul 59.5,Aug 57.2,Sep 55.4,Oct 62.0,Nov 59.0,Dec 52.9’

if re.search(p, s):
    m = re.findall(p, s)

print(m)

Примечание , если вы не знаете на 100%, что каждая входная строка содержит шаблон, который вы ищете, полезно проверить строку перед выполнением сопоставления. Один из способов проверить строку - воспользоваться предложением if, проверяющим наличие совпадения для re.search(p, s), где p - переменная для некоторого шаблона, а s - переменная для некоторой строки.

p = ‘[0-9][0-9]\.[0-9]’

Этот шаблон будет соответствовать: одно число di git 0-9 ('[0-9]'), за которым следует одно число di git 0-9 (' [0-9] '), за которым следует единственное вхождение периода ('. '), За которым следует одно число di git 0-9 (' [0-9] ' ). Например, этот шаблон будет соответствовать строке 19.9 или 40.0, но не 40. или 40. Строка '[0-9]' использует скобки для определения set в регулярном выражении. С набором любой из символов, включенных в квадратные скобки, может быть сопоставлен для этого одного места. Например, [A5] будет соответствовать A или 5, но не A5. Как и другие буквальные символы, квалификаторы повторения будут работать на множестве. Таким образом, мы можем использовать [A5]{1,2}, чтобы также сопоставить A5.

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

‘[0-9]{2}\.[0-9]{1}’ 

Этот шаблон выполняет те же действия, что и выше, но использует фигурные скобки для установки константы для числа повторений (а не для повторения набора дважды, как в предыдущем шаблоне).

‘\d{2}\.\d{1}’

В этом шаблоне используется специальный шаблон \d для соответствия любому десятичному числу di git ( ie любое число). Это эквивалентно использованию набора [0-9], как указано выше.

Стоит отметить, что технически . не нужно экранировать, так как символ точки '.' входит в класс «любой персонаж, который не является новой строкой. Тем не менее, это делает шаблон менее устойчивым, поскольку он (неточно) будет соответствовать любому символу, который не является новой строкой в этом месте. Например, он будет соответствовать 29.9 или 29A9 или 2909 (так как все они имеют не-символ новой строки в 3-й позиции.

Надеюсь, это поможет!

1 голос
/ 28 апреля 2020

re.findall(r'\d+[.]?\d*', string) получает меня ['48.0', '38.9', '39.9', '42.2', '47.3', '52.1', '59.5', '57.2', '55.4', '62.0', '59.0', '52.9']

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...