Подстановочный знак, соответствующий строке в Python regex поиск

Я думал, что напишу некоторый быстрый код для загрузки количества "вентиляторов", которые имеет страница Facebook.

По некоторым причинам несмотря на достаточное количество повторений я попробовал, я не могу добраться, следующий код для выбирания количества разветвляет HTML на входе. Ни одно из других решений, которые я нашел в сети правильно, не соответствует regex в этом случае также. Конечно, возможно иметь некоторый подстановочный знак между двумя битами соответствия?

Текст, против которого я хотел бы соответствовать, является "6 из X вентиляторов", где X произвольное число вентиляторов, страница имеет - я хотел бы получить это число.

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

import urllib
import re

fbhandle = urllib.urlopen('http://www.facebook.com/Microsoft')
pattern = "6 of(.*)fans" #this wild card doesnt appear to work?
compiled = re.compile(pattern)

for lines in fbhandle.readlines():
        ms = compiled.match(lines)
        print ms #debugging
        if ms: break
#ms.group()
print ms
fbhandle.close()
9
задан alex 25 June 2015 в 15:26
поделиться

3 ответа

import urllib
import re

fbhandle = urllib.urlopen('http://www.facebook.com/Microsoft')
pattern = "6 of(.*)fans" #this wild card doesnt appear to work?
compiled = re.compile(pattern)

ms = compiled.search(fbhandle.read())
print ms.group(1).strip()
fbhandle.close()

Вместо этого нужно было использовать re.search(). Используя re.match(), вы пытаетесь сопоставить шаблон с целым документом, но на самом деле вы просто пытаетесь сопоставить фрагмент внутри документа. Код выше печатается: 79,110. Конечно, к тому времени, как он будет напечатан кем-то другим, это будет, скорее всего, другое число.

12
ответ дан 4 December 2019 в 09:13
поделиться

не нужны регекс

import urllib
fbhandle = urllib.urlopen('http://www.facebook.com/Microsoft')
for line in fbhandle.readlines():
    line=line.rstrip().split("</span>")
    for item in line:
        if ">Fans<" in item:
            rind=item.rindex("<span>")
            print "-->",item[rind:].split()[2]

выход

$ ./python.py
--> 79,133
0
ответ дан 4 December 2019 в 09:13
поделиться

Эван Фосмарк уже дал хороший ответ. Это просто дополнительная информация.

У вас есть такая строка:

pattern = "6 of(.*)fans"

В общем, это плохое регулярное выражение. Если вводимый текст был:

«6 из 99 фанатов во всей галактике фанатов»

Тогда группа матчей (внутри скобок) будет:

«99 фанатов во всей галактике»

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

В этом случае на самом деле не имеет значения, соответствуете ли вы пробелу, потому что при преобразовании строки в целое число пробел игнорируется. Но давайте напишем шаблон, чтобы игнорировать пробелы.

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

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

Итак, нежадный шаблон:

pattern = "6 of\s+(.+?)\s+fans"

Другой:

pattern = "6 of\s+(\S+)\s+fans"

\ s означает «любой пробел» и будет соответствовать пробелу, табуляции и нескольким другим символам (например, " подача формы "). \ S означает «любое непробельное пространство» и соответствует всему, что \ s не соответствует .

Первый шаблон лучше, чем ваш первый с глупым вводным текстом:

«6 из 99 фанатов во всей галактике фанатов»

Он вернет группу совпадений всего 99 .

Но попробуйте этот другой глупый вводный текст:

«6 из 99 сумасшедших фанатов»

Он вернет группу совпадений из 99 сумасшедших .

Второй шаблон вообще не подходит, потому что слово «сумасшедшие» - это не слово «фанаты».

Хм. Вот последний шаблон, который всегда должен поступать правильно даже с глупыми входными текстами:

pattern = "6 of\D*?(\d+)\D*?fans"

\ d соответствует любой цифре ( '0' до '9' ). \ D соответствует любому нецифровому.

Это будет успешно соответствовать всему, что отдаленно недвусмысленно:

«6 из 99 фанатов во всей галактике фанатов»

Соответствующая группа будет 99 .

«6 из 99 сумасшедших фанатов»

Матч группа будет 99 .

«6 из 99 41 фанатов»

Не будет совпадать, потому что там было второе число.

Чтобы узнать больше о регулярных выражениях Python, вы можете прочитать различные веб- страницы . Напоминаем, что внутри интерпретатора Python выполните:

>>> import re
>>> help(re)

Когда вы «очищаете» текст с веб-страницы, вы иногда можете столкнуться с кодами HTML. В общем, регулярные выражения не являются хорошим инструментом для игнорирования разметки HTML или XML (см. здесь ); вам, вероятно, будет лучше использовать Beautiful Soup для синтаксического анализа HTML и извлечения текста, а затем регулярное выражение для захвата текста, который вам действительно нужен.

Надеюсь, это было интересно и / или познавательно.

11
ответ дан 4 December 2019 в 09:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: