[英]Understanding regex pattern used to find string between strings in html
我有以下html文件:
<!-- <div class="_5ay5"><table class="uiGrid _51mz" cellspacing="0" cellpadding="0"><tbody><tr class="_51mx"><td class="_51m-"><div class="_u3y"><div class="_5asl"><a class="_47hq _5asm" href="/Dev/videos/1610110089242029/" aria-label="Who said it?" ajaxify="/Dev/videos/1610110089242029/" rel="theater">
為了在videos/
和/"
之間拉出數字字符串,我使用發現的以下方法:
import re
Source_file = open('source.html').read()
result = re.compile('videos/(.*?)/"').search(Source_file)
print result
我已經嘗試使用Googling解釋(.*?)
在此特定實現中的確切工作方式,但是我仍然不清楚。 有人可以向我解釋嗎? 這就是所謂的“非貪婪”比賽嗎? 如果是,那是什么意思?
?
在這種情況下,是重復運算符( +
, *
和?
)上的特殊運算符。 在可用的引擎中,這導致重復是懶惰的 , 非貪婪的或不情願的或其他此類術語。 通常,重復是貪婪的,這意味着它應盡可能匹配。 因此,在大多數現代的Perl兼容引擎中,您有三種重復類型:
.* # Match any character zero or more times
.*? # Match any character zero or more times until the next match (reluctant)
.*+ # Match any character zero or more times and don't stop matching! (possessive)
可以在以下位置找到更多信息: http : //www.regular-expressions.info/repeat.html#lazy (不願意/懶惰),以及http://www.regular-expressions.info/possessive.html (所有格)我將跳過此答案中的討論)。
假設我們有字符串aaaa
。 我們可以將所有a與/(a+)a/
匹配。 從字面上看是
匹配一個或多個
a
,然后匹配a
。
這將匹配aaaa
。 正則表達式是貪婪的,將匹配盡可能多a
。 第一個子匹配是aaa
。
如果我們使用正則表達式/(a+?)a
勉強匹配一個或多個
a
然后匹配a
要么
匹配一個或多個a
s,至我們到達另一個a
也就是說,只匹配我們需要的東西。 因此,在這種情況下,與之匹配的是aa
和第一副配對是a
。 我們只需要匹配一個a
來滿足重復,然后后面跟一個a
。
當使用正則表達式在html標記,引號之類的內容中進行匹配時,這通常會保留很多,通常用於快速而骯臟的操作。 也就是說,使用正則表達式從非常大且復雜的html字符串或帶轉義序列的帶引號的字符串中提取可能會引起很多問題,但對於特定的用例而言,這是完全可以的。 因此,在您的情況下,我們有:
/Dev/videos/1610110089242029/
表達式需要匹配videos/
后跟零個或多個字符,后跟/"
。如果只有一個視頻URL,那很好,不用勉強。
但是我們有
/videos/1610110089242029/" ... ajaxify="/Dev/videos/1610110089242029/"
不用勉強,正則表達式將匹配:
1610110089242029/" ... ajaxify="/Dev/videos/1610110089242029
它會嘗試盡可能地匹配,並且/
和"
滿足.
就很好。由於勉強,匹配會在第一個/"
處停止(實際上它回溯了,但您可以單獨閱讀)。 因此,您只獲得所需的部分URL。
可以用一種簡單的方式來解釋:
.
:匹配任何內容(任何字符), *
:任意次數(至少零次), ?
:盡可能少的次數(因此不貪心 )。 videos/(.*?)/"
正則表達式匹配(例如)
videos/1610110089242029/"
第一個捕獲組返回1610110089242029
,因為任何數字都是“任何字符”的一部分,並且其中至少有零個字符。
?
導致這樣的事情:
videos/1610110089242029/" something else … "videos/2387423470237509/"
正確匹配為1610110089242029
和2387423470237509
而不是1610110089242029/" something else … "videos/2387423470237509
, 1610110089242029/" something else … "videos/2387423470237509
,因此“應盡可能少地次數”,因此應“非貪婪”。
的.
表示任何字符。 *
表示任意多次,包括零次。 ?
確實意味着不貪心; 這意味着它將嘗試捕獲盡可能少的字符,即,如果正則表達式遇到/
,則可以將其與匹配.
,但寧願不要因為.
是非貪婪的,並且由於正則表達式中的下一個字符很樂意匹配/
,因此.
不必。 如果您沒有?
那.
會吞噬整個文件的其余部分,因為它會一點點地砍去匹配盡可能多的內容,並且由於它匹配所有內容,因此它將永遠持續下去。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.