2012-07-17 271 views
-1

問題:需要得到一個字符串中的所有st。這樣做,但在備忘錄中只添加最後的結果,即st2。我如何獲得st和st2等?德爾福:TRegExpr

const 
    pattern = '<h3 class=.*><a class=.*>([a-zA-Z0-9а-яА-Я]+)</a></h3>'; 
var 
    r: TRegExpr; 
    s: string; 
begin 
r:=TRegExpr.Create; 
s:='<h3 class="yt-lockup-ellipsize"><a class="yt-uix-sessionlink yt-uix-tile-link result-item-translation-title"dir="ltr"title="Женщины"data-sessionlink="ei=CO_0s_S3oLECFQQZ3wodxl5sKw%3D%3D"href="/watch?v=E0MzksPjObU">st1</a></h3>'; 
s:=s + '<h3 class="yt-lockup-ellipsize"><a class="yt-uix-sessionlink yt-uix-tile-link result-item-translation-title"dir="ltr"title="Женщины"data-sessionlink="ei=CO_0s_S3oLECFQQZ3wodxl5sKw%3D%3D"href="/watch?v=E0MzksPjObU">st2</a></h3>'; 
r.Expression:=pattern; 
if r.Exec(s) then 
    REPEAT 
    Memo2.Lines.Add(r.Match[1]); 
    UNTIL not r.ExecNext; 

回答

4

呃。用正則表達式解析HTML =壞,不好想法。

不管怎樣,你的正則表達式是貪婪的,所以"<h3 class=.*><a class=.*>"部分匹配從你的第一個標籤到第二個標籤。你只需要通過第一個「>」擊中東西,所以嘗試像"<h3 class="[^>]*><a class="[^>]*>([a-zA-Z0-9а-яА-Я]+)</a></h3>"。 (您也可以使用惰性量詞,例如「。+?」而不是「。*」,但這比使用否定選項慢)。

請注意,這將無法正確處理嵌入的「>」在一個被引用的屬性 - 爲此,你需要更加努力工作。

  • 編輯:僅供參考,這裏的懶惰量詞版本:<h3\sclass=.+?><a\sclass=.+?>([a-zA-Z0-9а-яА-Я]+)</a></h3>(以下簡稱「\ s」爲空白字符 - 多少上最正則表達式更可靠的解析器)。

真的,你通過XML解析器運行這個好得多。

+0

謝謝。爲什麼不好主意?這是一個好主意嗎? :) – dedoki 2012-07-17 20:08:13

+2

一般來說,HTML不是常規語言,因此正則表達式無法捕獲所有可能的HTML編寫方式(不包括結束標籤等 - 這也會導致XML解析失敗)。我從最近的經驗談到:我的基於正則表達式的小型HTML解析器未能跳過註釋掉的HTML。啞。 C.f.,http://www.codinghorror.com/blog/2009/11/parsing-html-the-cthulhu-way.html一個有趣的拍攝。 此外,可以將HTML提供給基於正則表達式的解決方案,該解決方案可以完全鎖定解析器。 如果你有一個定義良好的域名,你可能確定。只要小心不可信的輸入。 – 2012-07-17 20:15:52

+2

只要好的想法去...如果我不得不做任何事情,除了最簡單的HTML解析,我會使用Delphi的Python來呼籲BeautifulSoup,這只是HTML解析器的試金石。 – 2012-07-17 20:17:24