ホームページ >バックエンド開発 >PHPチュートリアル >PHP実践正規表現(2):html要素を抽出する

PHP実践正規表現(2):html要素を抽出する

WBOY
WBOYオリジナル
2016-06-23 13:26:45988ブラウズ

この記事では、パターン修飾子、貪欲マッチングと非貪欲マッチング、Unicode モード、ルックアラウンドなどの正規表現の知識ポイントを HTML 要素を抽出して紹介します。
この記事を読む前に、同じシリーズの記事「PHP 実践正規表現 (1): 携帯電話番号の認証」をよく読んでおくことをお勧めします。

基本抽出

こんなフォームもあります

ユーザー名 職業
コービー・ブライアント バスケットボール選手
ジェイ・チョウ シンガー、ソングライター、プロデューサー、俳優、監督
Lionel Messi フットボール選手

そのソースコードは次のとおりです:

<table>  <thead>    <tr><th>用户名</th><th>职业</th></tr>  </thead>  <tbody>    <tr>      <td>Kobe Bryant</td><td>篮球运动员</td>    </tr>    <tr>      <td>Jay Chou</td><td>歌手、词曲创作人、制作人、演员、导演</td>    </tr>    <tr>      <td>Lionel Messi</td><td>足球运动员</td>    </tr>  </tbody></table>

次に、92cee25da80fac49f6fb6eec5fd2c22a の最初の a34de1251f0d9fe1e645927f19a896e8 要素を抽出する必要があります。最も単純な正規表現は次のようになります:

92cee25da80fac49f6fb6eec5fd2c22as+a34de1251f0d9fe1e645927f19a896e8.*fd273fcf5bcad3dfdad3c41bd81ad3e5

ここで、

  • s は実際の PHP 正規表現です (1): 携帯電話番号を確認する導入された文字グループの略語の 1 つで、復帰、ス​​ペース、タブ、その他の空白文字を表します

  • 数量子 + は、修飾される文字または文字グループの出現数が 1 以上であることを意味します

  • ドット文字 は、「任意の文字」に一致する正規表現の特別なメタ文字です

  • 終了タグ 内のスラッシュ / は、PHP 正規表現文字のパターン区切り文字であるため、スラッシュ文字を表すためにエスケープする必要があります。

しかし、実際には、そのような式は上記の 92cee25da80fac49f6fb6eec5fd2c22a から最初の a34de1251f0d9fe1e645927f19a896e8 要素を抽出できません

ここでの主な問題は、デフォルトでは改行文字 n と一致しないことです。この問題を解決するには 2 つの方法があります:

  • パターン修飾子 s を使用します。正規表現は /92cee25da80fac49f6fb6eec5fd2c22as+a34de1251f0d9fe1e645927f19a896e8.*fd273fcf5bcad3dfdad3c41bd81ad3e5/s または (?s)92cee25da80fac49f6fb6eec5fd2c22a です。 ;s+

    .*。パターン修飾子 s の機能は、ドット文字を改行文字と一致させることです。
  • すべての文字と一致するには、ピリオド文字を [sS] または [wW] または [dD] に置き換えます。正規表現は 92cee25da80fac49f6fb6eec5fd2c22as+a34de1251f0d9fe1e645927f19a896e8[sS]*fd273fcf5bcad3dfdad3c41bd81ad3e5です

Pattern Modifiers (パターン修飾子) について、ここで詳しく紹介する必要があります (PHP でサポートされているすべてのパターン修飾子を表示するには、ここをクリックしてください)。パターン修飾子は、正規表現のデフォルト ルールの一部を変更できます。一般的に使用されるパターン修飾子には、i、s、U、u などが含まれます。これらの一部については、ここでは説明しません。使用する場合は後ほど詳しく紹介します。ここでは主に、2 つの式メソッド /.../{modifier} と...(?{modifier}).... の違いを比較します。

例/a34de1251f0d9fe1e645927f19a896e8.*fd273fcf5bcad3dfdad3c41bd81ad3e5 / sa34de1251f0d9fe1e645927f19a896e8(?s).*fd273fcf5bcad3dfdad3c41bd81ad3e5 名前 (PHP マニュアル) 名前 (「通常のガイドライン」) スコープはサポートされていない場合があります

上の gif からわかるように、抽出結果には 1 つだけではなく 3 つの tr が含まれています。これは、正規表現の量指定子がデフォルトで 貪欲な一致 に設定されているためです。ここで、.* は最後に文字がなくなるまですべての文字に一致し、その後、92cee25da80fac49f6fb6eec5fd2c22a の最後の fd273fcf5bcad3dfdad3c41bd81ad3e5 に戻ります。正規表現内の fd273fcf5bcad3dfdad3c41bd81ad3e5 と一致して、一致プロセス全体が完了します。最終結果には 3 つの a34de1251f0d9fe1e645927f19a896e8 が含まれます。

パターン修飾子 U を使用して正規表現全体を非貪欲モードとして指定することも、非貪欲一致量指定子を使用して特定の量指定子を非貪欲モードとして指定することもできます:

  • 正規表現全体を非貪欲モードとして指定します:

    • /92cee25da80fac49f6fb6eec5fd2c22as+a34de1251f0d9fe1e645927f19a896e8.*fd273fcf5bcad3dfdad3c41bd81ad3e5/Us

    • または (?Us)92cee25da80fac49f6fb6eec5fd2c22as +a34de1251f0d9fe1e645927f19a896e8.*fd273fcf5bcad3dfdad3c41bd81ad3e5

  • 非貪欲量指定子:
    /92cee25da80fac49f6fb6eec5fd2c22as+a34de1251f0d9fe1e645927f19a896e8.*?fd273fcf5bcad3dfdad3c41bd81ad3e5/s

完全な貪欲数量子 (優先順位数量子と一致) と非貪欲数量子 (優先順位数量子を無視) を次の表に示します。

*
モード修飾子 /.../{修飾子} ...(?{修飾子})...
パターン修飾子 パターン内修飾子
事前定義された定数 パターン修飾子
正規表現全体 グループ(部分式)内にない場合、グループ(部分式)内にある場合は、それに続くすべての正規表現に影響します。 ) 式)、グループ化の残りの部分に影響します。グループ化がなく、正規表現全体の先頭に配置される場合、/.../{modifier} と同等になります。 その他のプログラミング言語
通常サポートされています
*? 出現する場合もあれば、出現しない場合もあり、出現回数に上限はありません ++? 最低1回、上限なし???発生回数0回または1回{m,n}{m,n}?発生回数ですm 以上、n 以下{m,}{m,}? は少なくとも m 回出現し、上限なし{0,n} {0,n}? は 0 回 -n 回出現します 指定されたコンテンツを含む行を抽出しますテーブルから に関するすべてのレコードを抽出したいと仮定すると、/a34de1251f0d9fe1e645927f19a896e8 を使用できます。* Athletes.*この式は Unicode エンコード環境の結果と一致しますが、GBK 環境では必ずしも一致するとは限りません。モード修飾子 u を使用して Unicode モードを指定できます: /a34de1251f0d9fe1e645927f19a896e8.*athlete.*fd273fcf5bcad3dfdad3c41bd81ad3e5/us
アスリート
Unicode モードでは、

code value

を使用して中国語の文字を置き換えることもできます:

/a34de1251f0d9fe1e645927f19a896e8.*x{8fd0}x{52a8}x{5458}.*fd273fcf5bcad3dfdad3c41bd81ad3e5/us

x{hex} の形式は、Unicode のコード値を表すために php 通常で使用されますコード値を使用する利点は、文字グループと組み合わせて範囲を表すことができることです。たとえば、[x{4e00}-x{9fff}] はすべての中国語の文字と一致することを意味します。

上記の式は結果と一致しますが、正しくありません。最初の a34de1251f0d9fe1e645927f19a896e8 から最後の fd273fcf5bcad3dfdad3c41bd81ad3e5 までの文字列全体と一致していることがわかります。

直観的には、正規表現で最初に「athlete」と一致し、次に左側で最も近い を探し、右側で最も近い を探します。しかし、実際には、正規表現は左から右に、つまり a34de1251f0d9fe1e645927f19a896e8 から開始して一致します。正規表現全体の一致を次の表に示します (空白文字は示されていません)。

一致値

/

a34de1251f0d9fe1e645927f19a896e8a34de1251f0d9fe1e645927f19a896e8.*アスリートさせてください.*b90dd5946f0946207856a8a37f441edffd273fcf5bcad3dfdad3c41bd81ad3e5a34de1251f0d9fe1e645927f19a896e8b6c5a531a458a2e790c1fd6421739d1cジェイ・チョウb90dd5946f0946207856a8a37f441edfb6c5a531a458a2e790c1fd6421739d1cシンガー、ソングライター、プロデューサー、俳優、監督b90dd5946f0946207856a8a37f441edf/私たち
ユーザー名 ;プロ01c3ce868d2b3d9bce8da5c1b7e41e5bfd273fcf5bcad3dfdad3c41bd81ad3e57943277d65306330563feb42dc8c705a92cee25da80fac49f6fb6eec5fd2c22aa34de1251f0d9fe1e645927f19a896e8b6c5a531a458a2e790c1fd6421739d1cコービー・ブライアントb90dd5946f0946207856a8a37f441edfb6c5a531a458a2e790c1fd6421739d1cバスケットボール
fd273fcf5bcad3dfdad3c41bd81ad3e5 fd273fcf5bcad3dfdad3c41bd81ad3e5

ここでは、両方の .* が予想よりも多くの文字に一致します。 .* が予想よりも多くの文字に一致する 2 番目の理由は、正規表現がデフォルトで貪欲一致パターンに設定されており、文字列の最後まで残りの文字列のすべての文字に一致し、その後最後の 5194ba175fd9c71e9a9f6e68244d73a8 に戻るためです。この問題は、貪欲でない一致モードを指定することで解決できます。ただし、正規表現は左から右に一致し、式内の a34de1251f0d9fe1e645927f19a896e8 は文字列内の最初の a34de1251f0d9fe1e645927f19a896e8 に一致するため、最初の .* が予想より多くの文字に一致するのは正常です。 * は、文字列の末尾までの残りのすべての文字と一致し、その後「athlete」に戻ります。

まず、非貪欲マッチングを使用した場合の結果を見てみましょう:

2 番目の .* マッチング文字がすでに必要なものであることがわかります。では、最初の .* が予想よりも多くの文字に一致するという問題を解決するにはどうすればよいでしょうか?

これまでの記事で紹介した知識だけを使えば解決する方法はあります。まず、PHP の preg_match_all 関数を非貪欲一致モードと組み合わせて使用​​することにより、左から右 (a34de1251f0d9fe1e645927f19a896e8...fd273fcf5bcad3dfdad3c41bd81ad3e5) までのすべての行を照合し、各行をスキャンしてフィルタリングします。 「アスリート」を含む行で十分です。

もちろん、純粋な正規表現を使用してこの問題を解決することもできます。正規表現の使用にある程度の経験がある友人なら、同じ位置に出現する可能性のある文字を表す 除外文字グループ[...] を簡単に思いつくかもしれません。 除外文字グループ は、同じ位置に出現できない文字を表します。その形式は [^...] であり、除外文字グループは左角かっこ [ の直後にある ^ で表されます。たとえば、[^d] は、一致する文字が数字以外の任意の文字であることを意味します。 (^a34de1251f0d9fe1e645927f19a896e8)* のような除外される部分式がある場合、a34de1251f0d9fe1e645927f19a896e8 を除外するには最初の .* を指定するだけです。ただし、残念ながら、正規表現には除外される部分式や除外されるグループはありません。この場合、 look-around のみを使用できます。 ) はどの文字にも一致せず、「その場で停止して周囲を見回す」ために使用されます。上記の式は負の逐次ルックアラウンド
を使用しており、その形式は (?!...) です。具体的には、 (.(?!a34de1251f0d9fe1e645927f19a896e8))* の場合、 . が文字に一致する場合は常に、現在の一致する文字の右側に a34de1251f0d9fe1e645927f19a896e8 が表示されない場合、一致は成功します。 完全な参照には以下が含まれます:

名前

表記 意味

特定の順序で見てくださいNegative look-around必ず逆の順序で見てください逆の順序で周りを否定的に見てください上記の正規表現はグループ(部分式)を持っているので、一致する結果には添字 0 だけでなく添字 1 も含まれます。ここでの添字 1 の結果は実際には役に立ちません。前に紹介した 非キャプチャ グループ化
(?=...) 右に見て、 look around は右側に表示されます Match
(?!...) look around の内容が右側に表示されない場合のみ、右側に目を向けます
(?<=... ) 左に見てください。左にある内容が左側に表示されている場合のみ、一致します
(? ルックアラウンドの内容が左側に表示されない場合のみ、左を見てください
を使用できます: /a34de1251f0d9fe1e645927f19a896e8(?:.() ?!a34de1251f0d9fe1e645927f19a896e8))*athletes.*fd273fcf5bcad3dfdad3c41bd81ad3e5/Us 実際の目的は、「Athlete」行を含むすべての項目を抽出することであり、上記では最初の項目のみが抽出されるため、preg_match 関数は次のことを行う必要があります。 preg_match_all に置き換えられます。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。