регулярное выражение, соответствующее строке, содержащей текст - PullRequest
0 голосов
/ 14 августа 2010

Мне нужно регулярное выражение, соответствующее

re.compile('userpage')


href="www.example.com?u=userpage&as=233&p=1"
href="www.example.com?u=userpage&as=233&p=2"

Я хочу получить все URL, которые имеют u = userpage и p = 1

Как я могу изменить приведенное выше регулярное выражение, чтобы найти оба u= страница пользователя и p = 1?

Ответы [ 6 ]

5 голосов
/ 14 августа 2010

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

from urlparse import *
urlparsed = urlparse('www.example.com?u=userpage&as=233&p=1')
# -> ParseResult(scheme='', netloc='', path='www.example.com', params='', query='u=userpage&as=233&p=1', fragment='')
qdict = dict(parse_qsl(urlparsed.query))
# -> {'as': '233', 'p': '1', 'u': 'userpage'}
qdict.get('p') == '1' and qdict.get('u') == 'userpage'
# -> True
4 голосов
/ 14 августа 2010
import lxml.html, urlparse

d = lxml.html.parse(...)
for link in d.xpath('//a/@href'):
    url = urlparse.urlparse(link)
    if not url.query:
        continue
    params = urlparse.parse_qs(url.query)
    if 'userpage' in params.get('u', []) and '1' in params.get('p', []):
        print link
2 голосов
/ 14 августа 2010

Регулярное выражение не является хорошим выбором для этого, потому что 1) параметры могут появляться в любом порядке, и 2) вам нужно сделать дополнительные проверки для разделителей запросов, чтобы вы не соответствовали потенциальным странностям, таким как "flu = userpage","sp = 1", "u = userpage% 20haha" или "s = 123".( Примечание: Я пропустил два из этих случаев в моем первом проходе! Как и другие.) Кроме того: 3) у вас уже есть хорошая библиотека для разбора URL-адресов в Python, которая работает за вас.

С помощью regex вам нужно что-то неуклюжее, например:

q = re.compile(r'([?&]u=userpage&(.*&)?p=1(&|$))|([?&]p=1&(.*&)?u=userpage(&|$))')
return q.search(href) is not None

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

def has_qparam(qs, key, value):
    return value in qs.get(key, [])

qs = urlparse.parse_qs(urlparse.urlparse(href).query)
return has_qparam(qs, 'u', 'userpage') and has_qparam(qs, 'p', '1')
0 голосов
/ 14 августа 2010

Это можно сделать с помощью взлома строк, но не следует.Он уже находится в стандартной библиотеке:

>>> import urllib.parse
>>> urllib.parse.parse_qs("u=userpage&as=233&p=1")
{'u': ['userpage'], 'as': ['233'], 'p': ['1']}

и, следовательно,

import urllib.parse
def filtered_urls( urls ):
    for url in urls:
        try:
            attrs = urllib.parse.parse_qs( url.split( "?" )[ 1 ] )
        except IndexError:
            continue

        if "userpage" in attrs.get( "u", "" ) and "1" in attrs.get( "p", "" ):
            yield url

foo = [ "www.example.com?u=userpage&as=233&p=1", "www.example.com?u=userpage&as=233&p=2" ]

print( list( filtered_urls( foo ) ) )

Обратите внимание, что это Python 3 - в Python parse_qs вместо urlparse.

0 голосов
/ 14 августа 2010

Чтобы убедиться, что вы случайно не совпадаете с такими частями, как bu=userpage, u=userpagezap, p=111 или zap=1, вам необходимо обильное использование элемента шаблона RE "word-border" \b.Т.е.:

re.compile(r'\bp=1\b.*\bu=userpage\b|\bu=userpage\b.*\bp=1\b')

Граничные элементы слова в шаблоне RE предотвращают вышеупомянутые, предположительно нежелательные «случайные» совпадения.Конечно, если в вашем приложении они не"нежелательны", т. Е. Если вы хотите, чтобы соответствовал p=123 и т. П., Вы можете легко удалить некоторые или всеслово-граничные элементы выше! -)

0 голосов
/ 14 августа 2010

/((u=userpage).*?(p=1))|((p=1).*?(u=userpage))/

При этом будут получены все строки, содержащие два искомых бита.

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