-1

問題: 文字列内のすべての st を取得する必要があります。そうしますが、メモには最後の結果、つまり st2 のみが追加されます。st や st2 などを取得するにはどうすればよいですか?

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

1 に答える 1

3

うーん。HTMLを正規表現で解析する=悪い、悪い考え。

とにかく、正規表現は貪欲であるため、"<h3 class=.*><a class=.*>"最初のタグから2番目のタグまですべて一致します。ヒットした最初の ">" だけを飲み込む必要があるので、 のようなものを試してください"<h3 class="[^>]*><a class="[^>]*>([a-zA-Z0-9а-яА-Я]+)</a></h3>"。(「.*」の代わりに「.+?」などの遅延量指定子を使用することもできますが、否定オプションを使用するよりも遅くなります。)

これは、引用符で囲まれた属性に埋め込まれた ">" を適切に処理しないことに注意してください。そのためには、もっと苦労する必要があります。

  • 編集: 参考までに、これは遅延量指定子のバージョンです: <h3\sclass=.+?><a\sclass=.+?>([a-zA-Z0-9а-яА-Я]+)</a></h3>(「\s」は空白文字です。ほとんどの正規表現パーサーでより信頼性が高くなります)。

実際、これを XML パーサーで実行する方がはるかに優れています。

于 2012-07-17T19:37:43.627 に答える