2014-10-25 2 views
1

Я пытаюсь собрать набор URL-адресов, используя BeautifulSoup, с очень конкретными критериями. URL-адреса, которые я хочу собрать, должны содержать /b-\d+ (/b-, а затем ряд числовых значений). Тем не менее, я хочу игнорировать все URL-адреса, содержащие View%20All, даже если в нем есть /b-\d+. Вот пример URL-адресов:Почему этот негативный взгляд на Python негативный взгляд не работает?

1. http://www.foo.com/bar/b-12312903?sName=View%20All 
2. http://www.foo.com/bar/b-832173712873?sName=View%20All 
3. http://www.foo.com/bar/b-1208313109283129 
4. http://www.foo.com/bar/b-2198123371239489?adCell=W3 

Учитывая вышеизложенное образца, действительные URL-адреса, которые я хочу собрать в # 3 и # 4. Я попытался с использованием различных отрицательного предпросмотра регулярные выражения, и они просто не работают для меня:

{"href" : re.compile(r"\/b-\d+.+(?!View\%20All)")} 
{"href" : re.compile(r"^.+\/b-\d+.+(?!View\%20All$)")} 

Может кто-нибудь сказать мне, что я делаю неправильно?

ответ

1
{"href" : re.compile(r"\/b-\d+.+(?!View\%20All)")} 
{"href" : re.compile(r"^.+\/b-\d+.+(?!View\%20All$)")} 

где вы ошибались?

когда мы даем (?!View\%20All) он утверждает, что View\%20All не может быть подобран сразу после предыдущего образца, который является .+

в действительности это означает, что внешний вид впереди всегда верно

иллюстрировать позволяет проверить, что соответствует на каждой из рисунка

http://www.foo.com/bar/b-12312903?sName=View%20All

/b- очевидно

\d соответствует 12312903

Теперь возникает проблема,

.+ матчей ничего такого, что делает отрицательное утверждение (?!View\%20All) успешным.

что говорят

. матчи ?s строка, которая остается непревзойденной является sName=View%20All, который не совпадает (?!View\%20All) в начальной позиции s поэтому всегда успешные согласующие линии 1 и линии 2

demo, чтобы получить четкое образ.

Fix ??

при использовании lookaround утверждений, зафиксировать позиции, откуда проверка начинается

говорят, используя регулярные выражения, как

(\/b-\d+)(\?|$)(?!sName=View\%20All) 

который будет соответствовать 3 и 4, как

http://regex101.com/r/aS5yS2/1

здесь ? или $ внутри строки фиксирует положение, в котором отрицательный asse начинается.

0
^.*?/b-\d+(?:(?!View%20All).)*$ 

Demo

Или намного быстрее

^.+?/b-\d+(?:[^V]+|V(?!iew%20All))*$ 
+0

Я не понимаю, почему "." необходимо в конце также ничего себе. эта демонстрация потрясающая – lollerskates