X
pm studio world wide news pj club
pm studio world wide news pj club
news, tech, music, film, sports, cg, translation, photo uploader
  • 2015-12-29
  • PJ Club
  • Using Regular Expressions with PHP / PHPの正規表現、エスケープが必要な文字サンプル、代表的な正規表現のサンプル
  • 今回のPJ Clubは、正規表現です。「正規表現とは、文字列の集合を一つの文字列で表現する方法の一つ」とwikipediaには記述されてます。
    簡単に言うと、文章の中にある文字列と検索したい文字列がマッチしているか、どうかをチェック出来ます。マッチしていれば、検索結果として表示します。
    しかし、この正規表現は結構難しく、中々思ったように動作してくれません。
    そこで、よく使う正規表現は、保存しておいて呼び出すようにしておけば、プログラムを組む時に考える手間が省けます。
    基本的な記述は下記のようになります。

    PHPの場合、
    "/正規表現記述/"

    JavaScriptの場合
    /正規表現記述/

    正規表現はいつ、どこで、何にで使うのか?一般的に多いのが、正しいメールアドレスの確認や文字の差し替えだと思います。
    正規表現を使って、検索するには、検索結果が1個だけの場合、preg_match("/正規表現記述/","検索対象文字列または文章",配列)関数、検索結果が複数の場合、preg_match_all("/正規表現記述/","検索対象文字列または文章",配列)関数を使います。
    もし、検索対象が文字列や文章ではなく、配列の場合、preg_grep("/正規表現記述/","検索対象配列")を使います。
    簡単な例で、下記のようあ文章があるとします。
    「pm studio world wide newsは、2014年から開始されたニュースサイトです。」
    この文章中に、「ニュースサイト」という文字列が存在するかどうかを見て見ます。

    $result=preg_match("/ニュースサイト/","pm studio world wide newsは、2014年から開始されたニュースサイトです。");
    echo $result;

    存在していれば、$resultは1 (true)、存在しなければ、0 (false)と表示されます。
    例のように分かりやすい文字列の場合は簡単でいいのですが、WebのURLのように内容を予測しなければならない場合、正規表現記述が役に立ちます。
    正規表現のリファレンスは下記のようになります。

    正規表現意味
    [文字][ ]内の文字の1文字
    [A-Z] 大文字のアルファベット1文字
    [^文字][ ]内の文字以外の1文字
    [0-9]、または、\d数字1文字
    [^0-9]、または、\Dアルファベット、数字、アンダースコア以外の1文字
    [a-zA-Z0-9]アルファベットか数字1文字
    [!-~]半角文字1文字
    \wアルファベットか数字かアンダースコア1文字
    \Wアルファベット、数字、アンダースコア以外の1文
    \s空白1文字
    \S空白以外1文字
    \n改行
    \tタブ
    * 0回以上の繰り返し
    +1回以上の繰り返し
    ?0回または1回の出現
    {n}n回の繰り返し
    {n,m}n回以上、m回以下の繰り返し
    {n,}n回以上の繰り返し
    .改行以外の1文字
    ^行頭
    $行末
    |いずれかの文字列
    ( )グループ化
    \直後のメタ文字\ ^ . $ * ? | ( ) [ ] { }をエスケープする
    i大小文字の違いを無視する
    sシングルラインモードにする
    mマルチラインモードにする
    uマルチバイト(UTF-8)対応

    正規表現では、エスケープが必要な文字があります。エスケープとは、「\」マークをつけて特殊動作を無効にさせることを意味します。分かりやすい例ですと、URLで使われる「/」です。「/」は特殊な文字で、そのまま使用するとエラー、またはうまく抽出できません。そこで、「\」を対象の文字の前につけて、特別な文字ではありませんよと、宣言します。

    エスケープ前エスケープ後
    \\\
    *\*
    +\+
    .\.
    ?\?
    {}\{\}
    ()\(\)
    [ ]\[\]
    ^\^
    $\$
    -\- [ ]の中に書く場合のみ
    |\|
    /\/
  • それでは、代表的正規表現例です。

    img tagを抽出
    "/<img[^>]*>/i"

    iframeを抽出
    "/<iframe[^>]*><\/iframe>/i"

    a tagを抽出
    "/<a[^>]*>/i"

    a tagと対象の文字列を抽出する
    "/<a[^>]*>(.*?)<\/a>/i"

    httpまたはhttpsではじまるURLを抽出
    "/https?:\/\/([^\"\']+)/i"

    YouTubeのURLを抽出
    "/https?:\/\/www.youtube.com\/[watch\?v=|embed\/]+[-_.!~*()\d\w;\/?:@&=+$,%#]+/i"

    VimeoのURLを抽出
    "/https?:\/\/[vimeo.com|player.vimeo.com\/video]+\/[-_.!~*()\d\w;\/?:@&=+$,%#]+/i"

    mailアドレスを抽出
    "/[\d\w]+[\d\w\._-]*@[\d\w_-]+[\d\w\._-]+/i"

    〒番号を抽出
    "/\d{3}-\d{4}/"

    電話番号を抽出
    "/\d{2,4}-\d{2,4}-\d{3,4}/"

    記述の仕方は、例えば、img tagを抽出したい場合、下記のようにします。

    $str="検索対象文字列、または文章";
    preg_match_all("/<img[^>]*>/i",$str,$result);

    $resultに検索結果が配列として入っています。
    この配列から結果を抜き出すには、下記のように記述します。

    foreach ($result as $key1){
         foreach ($key1 as $value){
              echo $value."<br>";
         }
    }

    まとめると、

    <?php
         $str="検索対象文字列、または文章";
         preg_match_all("/<img[^>]*>/i",$str,$result);
         foreach ($result as $key1){
              foreach ($key1 as $value){
                  echo $value."<br>";
              }
         }
    ?>

    上記のスクリプトでは、foreach()関数の中に、もう1個foreach()関数を使用しています。preg_match_all()関数の配列が、多次元配列と言って複数になっているためです。
    分かりにくいようであれば、下記のようにも出来ます。

    foreach ($result[0] as $value){
         echo $value."<br>";
    }

    複数の結果ではなく1個だけを表示するのであれば、preg_match()関数を使って下記のように記述します。

    <?php
         $str="検索対象文字列、または文章";
         preg_match("/<img[^>]*>/i",$str,$result);
         echo $result[0];
    ?>

    正規表現を毎回長く記述するのは大変ですから、PHPファイルを保存しておいて配列データを呼び出します。保存するPHPファイルを準備し、ファイル名は、ReExp.phpとします。

    <?php
         $ReExp=array(
                  'img' =>'/<img[^>]*>/i',
                  'iframe' =>'/<iframe[^>]*><\/iframe>/i',
                  'href' =>'/https?:\/\/([^\"\']+)/i',
                  'a_tag1' =>'/<a[^>]*>/i',
                  'a_tag2' =>'/<a[^>]*>(.*?)<\/a>/i',
                  'YouTube'=>'/https?:\/\/www.youtube.com\/[watch\?v=|embed\/]+[-_.!~*()\d\w;\/?:@&=+$,%#]+/i',
                  'vimeo' =>'/https?:\/\/[vimeo.com|player.vimeo.com\/video]+\/[-_.!~*()\d\w;\/?:@&=+$,%#]+/i',
                  'mail' =>'/[\d\w]+[\d\w\._-]*@[\d\w_-]+[\d\w\._-]+/i',
                  'zip' =>'/\d{3}-\d{4}/',
                  'tel'=>'/\d{2,4}-\d{2,4}-\d{3,4}/',
                  'mail2' =>'/^([\d\w])+([\d\w\._-])*@([\d\w_-])+([\d\w\._-]+)+$/i',
                  'zip2' =>'/^\d{3}-\d{4}$/',
                  'tel2'=>'/^\d{2,4}-\d{2,4}-\d{3,4}$/',
                  'YouTubeID1' =>'/\?v=([^&]+)/i',
                  'YouTubeID2' =>'/\/embed\/([^?]+)/i'
                  );
    ?>

    'img' =>'/<img[^>]*>/i',のように"要素名"=>"配列データ"とすると、$ReExp["要素名"]で、配列データを取得出来ます。

    まとめると、

    <?php
         //phpファイル読み込み
         require_once("ReExp.php");

         $str="検索対象文字列、または文章";
         preg_match_all($ReExp["要素名"],$str,$result);
         foreach ($result as $key1){
              foreach ($key1 as $value){
                  echo $value."<br>";
              }
         }
    ?>
  • これで、文章から検索対象文字列を抽出できます。
    ところで、メール、〒番号、電話番号ですが、上記スクリプトを使って抽出する場合、マッチしている可能性をさぐるものです。そのため、フォーム (form)タグなどから送信する時は、もう少し厳密にチェックする必要があります。
    その場合、preg_match()関数を使って、記述が正しいか、誤りかをチェックをします。
    正規表現は下記のようにします。

    メール ($ReExp["mail2"])
    "/^([\d\w])+([\d\w\._-])*@([\d\w_-])+([\d\w\._-]+)+$/i"

    〒番号 ($ReExp["zip2"])
    "/^\d{3}-\d{4}$/"

    電話番号 ($ReExp["tel2"])
    "/^\d{2,4}-\d{2,4}-\d{3,4}$/"

    では、メールアドレスをチェックしてみます。

    <?php
         require_once("ReExp.php");

         $str="pmstudio@pmstudio.com";
         $result=preg_match($ReExp["mail2"],$str);
         if($result){
              echo "正しいメールアドレスです。";
         } else {
              echo "正しいメールアドレスではありません。";
         }
    ?>

    メールアドレスが正確で正しければ、1 (true)を結果として得られ、正しくなければ、0 (false)として結果が返されます。

    YouTubeの動画IDだけを抽出するには?

    Webでよく見かける質問にYouTubeの動画IDだけ取得したいと言うのがあります。
    これも正規表現で取得出来ます。
    上記の例で、YouTubeのURL抽出を記述しましたが、それを利用します。

    $str="検索対象文字列、または文章";
    preg_match_all($ReExp["YouTube"],$str,$result);

    とすると、$resultにYouTubeのURLが配置されます。そこから動画IDだけを抽出します。
    正規表現は、埋め込み(embed)でない場合 ($ReExp["YouTubeID1"])、

    "/\?v=([^&]+)/i"

    埋め込み(embed)の場合 ($ReExp["YouTubeID2"])、

    "/\/embed\/([^?]+)/i"

    となります。

    ちょっと、強引ですが、まとめてみると

    <?php
         require_once("ReExp.php");

         $str="検索対象文字列、または文章";
         preg_match_all($ReExp["YouTube"],$str,$result);
         foreach ($result as $key1){
              foreach ($key1 as $key2){
                  $checkID=preg_match($ReExp["YouTubeID1"],$key2,$result2);
                  if($checkID){
                      $YouTubeID .= $result2[1]."<br>";
                  }
                  $checkID=preg_match($ReExp["YouTubeID2"],$key2,$result2);
                  if($checkID){
                      $YouTubeID .=$result2[1]."<br>";
                  }
              }
         }
         echo $YouTubeID;
    ?>

    これで文章の中にYouTubeのURL、または埋め込み用URLが存在するとYouTubeのIDだけを抽出します。
  • source : pm studio world wide news
Recent Post
Latest News
Billboard Hot 100
Top 10
  • No.1
    Thank U, Next
    Ariana Grande
  • No.2
    Girls Like You
    Maroon 5 & Cardi B
  • No.3
    Sicko Mode
    Travis Scott
  • No.4
    Happier
    Marshmello & Bastille
  • No.5
    Lucid Dreams
    Juice WRLD
  • No.6
    Shallow
    Lady Gaga & Bradley Cooper
  • No.7
    Zeze
    Kodak Black, Travis Scott & Offset
  • No.8
    Fine China
    Future & Juice Wrld
  • No.9
    Better Now
    Post Malone
  • No.10
    Sunflower
    Post Malone & Swae Lee
BBC Radio 1 Singles 40
Top 10
  • No.1
    Thank U, Next
    Ariana Grande
  • No.2
    Shallow
    Lady Gaga & Bradley Cooper
  • No.3
    Woman Like Me
    Little Mix & Nicki Minaj
  • No.4
    Let You Love Me
    Rita Ora
  • No.5
    Funky Friday
    Dave & Fredo
  • No.6
    Without Me
    Halsey
  • No.7
    Sunflower
    Post Malone & Swae Lee
  • No.8
    Zeze
    Kodak Black, Travis Scott & Offset
  • No.9
    Guiding Light
    Mumford & Sons
  • No.10
    Girls Like You
    Maroon 5 & Cardi B
  • Editor: Toshio Maeoka / pm studio
    pm studio world wide news © 2014-2018 . All Rights Reserved
^
to TOP