「PHP」カテゴリーアーカイブ

素人でもできる! WEBページの情報を抽出する

素人でもできる! WEBページの情報を抽出する

ネットショップをされている方なら、WEBサイトで『New Item』や『目玉商品』を紹介するときに、各商品ページの情報(価格、商品名、リンク先の情報など)を抽出できたら、便利ですよね。それぞれの商品ページを開かなくても、必要な情報だけ取り出してみましょう。また、カテゴリページで複数の商品が並んでいるときに、それぞれの商品IDだけでも取り出せたら便利なことありませんか?例えば商品を出品した順番(もしくは古い順番)に商品IDを取りだしたいときなど。

①商品ページの情報(価格、商品名、リンク先の情報など)を抽出する。
②カテゴリページの商品IDを取りだす。

以上、2点について、PHPを使った素人レベルの解決策を考えていきますね。

作るのはPHPファイルです。phpはhtmlを生成してくれる言語です。
(※phpとhtmlは混在できます。<?php ・・・  ?> で囲まれた部分がphpです。)
PHPファイルはサーバー側で動くので、レンタルサーバーを借りている方は、サーバーに作ったファイルをアップします。レンタルサーバーがない方は、完全に無償で利用できるPHP開発環境の『XAMPP(ザンプ)』をインストールして、インストールされた[xampp]フォルダの直下にある[htdocs]フォルダにファイルを保存します。

まずは、商品ページの情報(価格、商品名、リンク先の情報など)を抽出します

WebサイトからWebページのHTMLデータを収集して、特定のデータを抽出することをWebスクレイピングといいます。これから、PHPのライブラリである『PHP Simple HTML DOM Parser』を使ってWebスクレイピングしちゃいます。ここで作るphpファイル名を「index.php」としますね。
考え方の順番としては、

【1】まずは、↓↓↓ここ↓↓↓から、ライブラリのsimple_html_dom.phpをダウンロードして、index.phpと同じフォルダに保存し、それを読み込みます。

require_once ‘simple_html_dom.php’;
include_once(‘simple_html_dom.php’);

※require_once、include_onceは同じ働きをします。

【2】str_get_html、file_get_html、file_get_htmlなどのヘルパー関数を使って、simple_html_domオブジェクト(= $html)を生成(=WEBページの情報を取得)します。

// 文字列から
$html = str_get_html( ‘<html><body>Hello!World!</body></html>’ );
// URLから
$html = file_get_html( ‘http://test.com/sample.html’ );
// HTMLファイルから
$html = file_get_html( ‘test.html’ );

【3】ページ内の要素についている「ID名」や「クラス名」を使って、生成したオブジェクト(= $html)から特定の要素を探しだして、変数(=$ret )に代入します。

// id属性がcontentsのすべての要素を取得する
$ret = $html->find( ‘#contents’ );
// class属性がsubのすべての要素を取得する
$ret = $html->find( ‘.sub’ );

【4】抽出した値を配列型の変数に代入して、ブラウザ上に書き出すようにHTMLコードを生成させます。

クラス属性が「catch_copy」である要素があれば、繰り返し全部(=foreach(){ })、それを配列(=$parts[0])に代入し、ブラウザ上に書き(=echo)出します。

foreach($html>find(‘.catch_copy’) as $parts[0]){
  echo $parts[0];
}

それでは、実際にコードをかいてみて、「index.php」のファイル名で保存しましょう。

仮に取りだしたい商品ページについて
1)商品IDが「15000」として、
2)商品ページのURLが「http://sample.com/shouhin/15000/」と仮定します。
ブラウザ上で、「15000」と入力して送信ボタンを押すと、商品ページの情報を抽出してブラウザ上に表示されるようにコードを組んでいきます。

まずは、結果から。

ブラウザで「index.php」ファイルをひらきます。
レンタルサーバーのURLで開くなら、アドレスバーに「http://サーバー名/フォルダ名/index.php」と入力します。PCにXAMPPをインストールし,PHPファイルを[htdocs]フォルダの直下に保存したなら、XAMPPを起動し、アドレスバーに「localhost/index.php」と入力します。

ブラウザに下のような入力フォームと送信ボタンが表示されます。
2018081301

フォームに「15000」と入力し、送信ボタンを押します。

2018081302

すると、下のように商品IDが15000の商品ページの情報が取得され、表示されます。

2016081303

では、PHPファイルを作りましょう。

メモ帳にコードを書いて、ファイル名を「index.php」で保存すればOKです。
スクレイピングしたいURLは、「http://item.rakuten.co.jp/shopurl/15000/」(=$site)です。

①きまり文句です。
②ライブラリのsimple_html_dom.phpを呼び込みます。
③webページへのリクエスト送信方法を「POST」で行います。(「POST」か「GET」で指定する必要がありますが、理解することは不要です。「POST」で宣言すればいいので、定型文的なものと考えてください。)
④URL(=$site)から、ヘルパー関数(=file_get_html)を使ってオブジェクト(=$html)を生成(スクレイピング)します。
⑤商品IDとして、フォームのテキスト入力欄に入力した値(=’15000’)を取得します。
※商品IDはフォームに入力した値(=site)から取得(=$_POST[‘site’])します。
⑥生成したオブジェクト(=$html)から、特定のクラス名を持つ要素を探し出し、配列(=$parts[])に代入し、ブラウザ上に書き(echo)出します。

<?php
/**********************************************
リクエストURLの生成
************************************************/

//カレント言語を日本語に指定mb_language(“Japanese”);   

mb_language(“Japanese”);・・・・①

//PHP内部のエンコーディングを’UTF-8’に指定

mb_internal_encoding (“utf-8”);       ・・・・①

session_start();               ・・・・①

//simple_html_dom.phpファイルの読み込み

include_once(‘simplehtmldom_1_5/simple_htmldom.php’);   ・・・・②

//フォームからURL取得

$site=”;

if ($_SERVER[‘REQUEST_METHOD’] === ‘POST’) {$site = htmlspecialchars(‘http://item.rakuten.co.jp/shopurl/’.$_POST[‘site’].’/’);  ・・・・③

$err = false;

//スクレイピングしたいURLを指定
$url = $site;

//「simple_html_dom.php」のヘルパー関数を利用してスクレイピング

$html = file_get_html($url);          ・・・・④

header(“Content-type:text/html;charset=UTF-8”);   ・・・・①

?>

<html lang=”ja”>
<head>
<meta http-equiv=”content-type” content=”text/html; charset=UTF-8″>
<title>「<?php echo$_POST[‘site’]; ?>」の要素抽出</title></head>
<body>

<!–#####################################################

(1)商品管理番号より、商品ページのURLを取得
(2)スクレイピングにより、要素抽出(「file_get_html」という「simple_html_dom.php」のヘルパー関数を使うか、もしくは、「Curl」を使う)
(3)連想配列として、データ格納(もしくは、ブラウザ上でデータをバインディング)して、
HTMLコード生成

####################################################–>
<div style=”margin-left:50px;”>

//フォームの部品(テキスト入力欄)を作成し、入力された値を取得する。
<form action=”<?php echo $_SERVER[‘PHP_SELF’]; ?>” method=”post”>・・・・①

<span>商品管理番号:</span>
<input type=”text” name=”site” value=”<?php if($_POST[‘site’]){ ?><?=$_POST[‘site’]?><?php } ?>” size=”30″>             ・・・・⑤
<input type=”submit” name=”submit” value=”送信”>

</form>

//要素を抽出して、書き出す。
<?php if($_POST[‘site’]){ ?>

<h2><?php echo$_POST[‘site’]; ?>の要素を抽出します。</h2><br>
</div>
<div>
<table id=”header”>
<tr>
 <!–キャッチコピー–>
<td class=”midashi”>
<?php echo “キャッチコピー”; ?>
</td>
<td>
<?php foreach($html->find(‘.catch_copy’) as $parts[0]){ ?>   ・・・・⑥
<?php echo $parts[0]; ?>
<?php } ?>
</td>
</tr>
<tr>
 <!–商品名:–>
<td class=”midashi”>
<?php echo “商品名:”; ?>
</td>
<td>
<?php foreach($html->find(‘.item_name’) as $parts[1]){ ?>   ・・・・⑥
<?php echo $parts[1]; ?>
<?php } ?>
</td>
</tr>
<tr>
<!–商品お問い合わせ番号–>
<td class=”midashi”>
<?php echo “商品お問い合わせ番号”; ?>
</td>
<td>
<?php foreach($html->find(‘.item_number’) as $parts[2]){ ?>  ・・・・⑥
<?php echo $parts[2]; ?>
<?php } ?>
</td>
</tr>
<tr>
<!–税抜価格–>
<td class=”midashi”>
<?php echo “税抜価格”; ?>
</td>
<td>
<?php foreach($html->find(‘.price2’) as $parts[3]){ ?>     ・・・・⑥
<?php echo $parts[3]; ?>
<?php } ?>
</td>
</tr>
<tr>
<!–税込価格・送料–>
<td class=”midashi”>
<?php echo “税込価格・送料”; ?>
</td>
<td>
<?php foreach($html->find(‘.tax_postage’) as $parts[4]){ ?>  ・・・・⑥
<?php echo $parts[4]; ?>
<?php } ?>
</td>
</tr>
<tr>
<!–インフォメーション–>
<td class=”midashi”>&nbsp;
</td>
<td>
<?php foreach($html->find(‘.item_desc > font’) as $parts[5]){ ?> ・・・・⑥
<?php echo $parts[5]; ?>
<?php } ?>
</td>
</tr>

</table>
</div>

<?php } ?>

<style type=”text/css”>
<!–
#header{
margin-left:30px;
position: absolute;
top:100px;
left:50px;
width:1000px;
}
th,td{
border:solid 1px #ccc;
}
.midashi{
width:250px;
color:#0000ff;
font-weight: bold;
}

–>
</style>
</body>
</html>

以上は、楽天の商品ページから特定の要素を抜き出し、ブラウザに書き出すphpです。
楽天の商品ページを開いて「F12」キーを入力すると開発者用のウィンドウが表示されますが、そこで、特定の要素が含まれるドキュメントを確認すると、それぞれ、特定のクラス名が自動で付けられていることが確認できます。
これを利用して、すでにアップした商品ページから情報を抜き取ることに成功しました!

次に、カテゴリページの商品IDを取りだします

同様にして、楽天の新着情報ページ(検索結果ページ)に表示されている複数の商品の商品IDを抽出してみます。

新着情報ページが3ページ目の場合のURLは「http://search.rakuten.co.jp/search/mall/ブランドスーパー楽天市場店/?p=3&s=4&v=3」です。3ページ目の場合、クエリ文字列(?—)の変数「p」に対して取る値が「3」なので、クエリ文字列は「?p=3&・・・」で表されます。同様に4ページ目の場合はクエリ文字列は「?p=4&・・・」となります。

フォームのテキストエリアに何ページ目の情報を取得するのか入力して、送信ボタンを押すと結果が返るようにコードを組んでいきます。

まずは、結果から。

ブラウザで「index.php」ファイルをひらきます。
ブラウザに下のような入力フォームと送信ボタンが表示されます。

2016081401

フォームに「3」と入力し、送信ボタンを押します。

2016081402

すると、下のように3ページ目に表示されている商品の商品IDの情報が取得され、表示されます。

2016081403

では、PHPファイルを作りましょう。

スクレイピングしたいURLは、3ページ目の「http://search.rakuten.co.jp/search/mall/ブランドスーパー楽天市場店/?p=3&s=4&v=3」(=$site)です。考え方は商品ページから情報を抽出する時と同じです。
※URLでかな文字は使えませんので、「ブランドスーパー楽天市場店」の部分はパーセントコードに変換(エンコード)しておきます。
「ブランドスーパー楽天市場店」⇒「%83u%83%89%83%93%83h%83X%81%5b%83p%81%5b%8ay%93V%8es%8f%ea%93X」

<?php
/**********************************************
リクエストURLの生成
************************************************/
//カレント言語を日本語に指定
mb_language(“Japanese”);//PHP内部のエンコーディングを’UTF-8’に指定
mb_internal_encoding (“utf-8”);session_start();//simple_html_dom.phpファイルの読み込み<br>
include_once(‘simplehtmldom_1_5/simple_html_dom.php’);//フォームからURL取得
$site=”;
$url=”;
$html=”;
if ($_SERVER[‘REQUEST_METHOD’] === ‘POST’) {$site = htmlspecialchars(‘http://search.rakuten.co.jp/search/mall/%E3%83%96%E3%83%A9
%E3%83%B3%E3%83%89%E3%82%B9%E3%83%BC%E3%83%91%E3%83%BC%E6%A5
%BD%E5%A4%A9%E5%B8%82%E5%A0%B4%E5%BA%97/
?p=’.$_POST[‘site’].’&s=4&v=3′);$err = false;//スクレイピングしたいURLを指定<br>
$url = $site;//「simple_html_dom.php」のヘルパー関数を利用してスクレイピング
$html = file_get_html($url);
}header(“Content-type:text/html;charset=UTF-8”);
?>
<html lang=”ja”>
<head>
<meta http-equiv=”content-type” content=”text/html; charset=UTF-8″>
<title>「<?php echo$_POST[‘site’]; ?>」ページ目の商品IDの抽出</title></head>
<body>
<p>新着順で商品一覧表示をした時の●ページ目の商品IDを抽出します。</p>
<P>何ページ目かを入力して、送信ボタンを押してください。</P>
<P>1ページ目のURLは以下となります。</P>
<a href=”http://search.rakuten.co.jp/search/mall/%E3%83%96%E3%83%A9%E3%83%B3
%E3%83%89%E3%82%B9%E3%83%BC%E3%83%91%E3%83%BC%E6%A5%BD%E5%A4
%A9%E5%B8%82%E5%A0%B4%E5%BA%97/?s=4&v=3&x=0″ target=”_blank”><p>http://search.rakuten.co.jp/search/mall/ブランドスーパー楽天市場店/?s=4&v=3&x=0</p></a>
<p>抽出したページは以下、URLです。<br><?php echo $site;?></p><div style=”margin-left:50px;”><form action=”<?php echo $_SERVER[‘PHP_SELF’]; ?>” method=”post”>

<span>ページ番号:</span>
<input type=”text” name=”site” value=”<?php if($_POST[‘site’]){ ?><?=$_POST[‘site’]?><?php } ?>” size=”30″>
<input type=”submit” name=”submit” value=”送信”>

</form>
</div>

<?php if($_POST[‘site’]){ ?>

<h2><?php echo$_POST[‘site’]; ?>ページ目の商品IDを抽出します。</h2><br>

<div>
<?php $n=0 ?>
<table id=”header”>

<tr>
<td style=”text-align:left;”>

<?php foreach($html->find(‘.price > a‘) as $part){ ?>

<?php $pieces = explode(“/”, $part->href); ?>
<?php echo $pieces[4].'<br>’; ?>
<?php $n = $n + 1; ?>

<?php } ?>

</td>
</tr>

</table>
</div>
<p id=”kosuu”><?php echo $n; ?>個の商品を抽出しました。</p>

<?php } ?>

<style type=”text/css”>
<!–
#header{
margin-left:30px;
position: absolute;
top:300px;
left:50px;
width:1000px;
}
th,td{
border:solid 1px #ccc;
}
#kosuu{
position: absolute;
top:1150px;
left:50px;

}
–>
</style>
</body>
</html>

前回に追加した内容としては、要素を抽出する際の手法です。検索結果ページ内に表示されている商品のリンク先情報に各商品IDの情報が含まれているので、
まずリンク先情報を取り出します。

$html->find(‘.price > a‘) as $part

└※クラス名が「price」の<a>タグの情報を探し、$partに代入する

さらに、取り出したリンク先情報のURLを「/」で分割し、配列($pieces)に代入して、4番目の値($pieces[4])を取り出します。
取り出した値が商品IDとなるので、これを列挙します。

$pieces = explode(“/”, $part->href);
echo $pieces[4].'<br>’;

以上、足早に書いてきましたが、何かのヒントになりますか?
得た知識をリアルな現場に応用して、日々の作業を軽くしていきましょう!

foreach文を利用する

PHP基礎 配列の操作/連想配列/Webフォームの作成 – Qiita

foreach文を利用するには、2つの書式がある。
①
foreach($配列名 as $一時変数名){
    繰り返し処理
}

②
foreach($配列名 as $キーの一時変数名 => $値用の一時変数名){
    繰り返し処理
}

①の場合、配列の各値は先頭の要素から順番に一時変数に代入され、
 全要素に対して繰り返し処理が行われる。
②の場合、配列の各キーが順番にキー用の一時変数に代入され、
さらに配列の各値が順番に値用の一時変数に代入されて、全要素に対して繰り返し処理が行われる。
foreach文をfor文で書き直した場合、同じ結果になるもの

$fruits = array(1 => 'apple',
          2 => 'banana',
          3 => 'lemon',
          4 => 'orange');

foreach($fruits as $key => $value){
     print "{$key} {$value}" ;
}

$n = count($fruits);
for($i = 1; $i <= $n ; $i++ ){
  print "{$i} {$fruit[$i]}";
}

implode() 配列から文字列を作成する関数
http://php.net/manual/ja/function.implode.php

asort()関数 配列の値を基準に並べ替えることができる。キーと値の組み合わせは保持される
http://php.net/manual/ja/function.asort.php

sort()関数 配列の並べ替えにおいて最も単純な関数。並べ替えの際に、配列のキーを数に変えて付け直すため数値配列のみで使用する
http://php.net/manual/ja/function.sort.php

ksort()関数 キーを基準に並べ替えることができる。
http://php.net/manual/ja/function.ksort.php

PHPのページが真っ白になる時の対処

http://www.h-fj.com/blog/archives/2012/10/15-105123.php

1).PHPのエラーを表示する

PHPでエラーが発生した時に、何も出力しない設定になっていたことが主な原因です。
⇒PHPの設定ファイル(php.ini)の「display_errors」の行で指定します。
display_errors=On」にすると、エラーメッセージが表示されます。
一方、「display_errors=Off」にすると、エラーメッセージは表示されません。

通常は、公開しているWebページで、PHPのエラーメッセージが表示されるのは、セキュリティ的に好ましくありません。そのため、エラーがあってもエラーメッセージを表示しない設定にしています。
2).「<?」~「?>」をPHPとみなす

PHPのプログラムは、「<?php」と「?>」で囲むことが多いです。
PHPのコードの開始タグを、「<?php」から「<?」に変えることもできます。
この設定は、PHPの設定ファイルの「short_open_tag」の行で行います。
short_open_tag=On」にすると、PHPの開始タグを「<?」と書くことができます。
一方、「short_open_tag=Off」にすると、開始タグを「<?php」と書かなければなりません。

3).XML宣言を削除するとページが表示された理由

「short_open_tag=On」になっていると、「<?」はPHPの開始タグとみなされます。
一方、XML宣言は「<?xml version=”バージョン番号” encoding=”文字コード”?>」のように書き、開始タグに「<?」が含まれます。
そのため、PHPのページの中にXML宣言があると、XML宣言をPHPと解釈しようとしてしまい、エラーが発生します。
ところが、「display_errors=Off」になっていると、エラーメッセージは表示されません。
この2つが重なって、「XML宣言を入れるとページが表示されなくなる」という現象が起こります。

PHPの設定を変えずにこの問題を回避するには、XML宣言をPHPで出力すれば良いです。
具体的には、XML宣言の行を以下のように書き換えます。

<?php echo(‘<?xml version=”バージョン番号” encoding=”文字コード”?>’); ?>
4).  .htaccessでPHPの設定を変える
Webサーバー(Apache)の設定によっては、.htaccessでPHPの設定を変えることができる場合があります。
その場合、.htaccessでdisplay_errorsの設定を変えて、特定のディレクトリやファイルでだけ、PHPのエラーメッセージを出力するようにすることができます。
また、short_open_tagの設定を変えて、short_open_tagをオン(またはオフ)にすることもできます。

例えば、あるディレクトリのPHPのページでエラーが発生して、表示が真っ白になったとします。
この場合、そのディレクトリに以下の内容の.htaccessファイルを置き、PHPのエラーメッセージを表示して、原因を探るようにします。
そして、エラーの対策が終わったら、.htaccessファイルから以下の行を削除します。

php_flag display_errors On
また、あるディレクトリでは、short_open_tagをオフにしたいとします。
その場合、そのディレクトリに以下の内容の.htaccessファイルを置きます。

php_flag short_open_tag Off

mb_convert_encodingに潜む問題

http://qiita.com/shoyan/items/d9f7c014ba8003e19b57

mb_convert_encoding ( string $str , string $to_encoding [, mixed $from_encoding ] )
文字エンコーディングを変換する関数です。
第3引数の $from_encoding には変換前の文字エンコーディング名を指定しますが、
ここを“auto”と指定しておくと、環境によっては

Warning: mb_convert_encoding(): Unable to detect character encoding

のようなエラーが発生し、文字エンコーディングの変換が失敗する場合があります。
ですので、”auto” は極力使わず、文字エンコーディングを指定することをおすすめします。

なぜこのようなエラーが発生するかというと、
autoはphp.iniの言語設定によって挙動が変わってしまうからです。

mb_convert_encodingとうまく付き合うには

①autoは使わない
autoは指定せずに適切なエンコーディングを指定しましょう。
言語設定が Japanese の場合は “ASCII,JIS,UTF-8,EUC-JP,SJIS” です。
autoを指定したい場合は代わりに、”ASCII,JIS,UTF-8,EUC-JP,SJIS”と設定しましょう。
mb_convert_encoding ( string $str , string $to_encoding , “ASCII,JIS,UTF-8,EUC-JP,SJIS”)

②php.iniを変更する
もしくは、php.iniに mbstring.language = Japanese を指定しておけばautoと指定した場合は”ASCII,JIS,UTF-8,EUC-JP,SJIS”として認識されます。
しかし、この方法はphp.iniとの依存関係が強くなるためあまりおすすめできません。

③mb_language関数を使用する
php.iniを変更するのが難しい場合は、mb_convert_encodingの前に
mb_language(“Japanese”); と指定する方法もあります。
—————————————————————————————-

★!! 注意 !!★  mb_convert_encoding関数には配列を引数として渡すことはできない

例)$match_titleが配列(Array)の場合、文字列に変換しようとして以下、コードを書くと

$match_title = mb_convert_encoding($match_title,”UTF-8″,”SJIS”);

↓↓↓↓↓↓↓下の様なエラーが出る↓↓↓↓↓↓↓

Notice: Array to string conversion in C:\php\nobuneko\test.php on line 23

「Array(配列)を文字変換(?)しようとしている」????

なので、配列の要素を限定して、

正規表現 -タグの変換-

既存タグ: <font color=”blue”>test</font>

生成タグ: <span style=”color:$1;”>test</span>

※ $1はキャプチャされた文字列が入る

 H:\正規表現入門(1) – 正規表現を使ってみよう  アシアルブログ.mht

まず、fontタグを検索して、置換後も引き継ぎたい文字列を保持しておきます
(上の例では、「blue」と「test」)。文字列を保持しておくことを、「キャプチャ」といいます。検索とキャプチャには、以下のような正規表現が使えます。

<font color=”(.+)”>(.+)</font>

次に、置換用の文字列を用意します。

<span style=”color:$1″>$2</span>
$1、$2というのは、キャプチャされた文字列の入る場所です。$1には「blue」、$2には「test」が入ります。

<font color=”(…)“>test</font>
※マッチした部分の値を取得するには、()(カッコ)でキャプチャを取ります。

(…)とすれば、任意の3文字をキャプチャします。
キャプチャされた文字列は、$1、$2といった「$ + 連番の数字」という名前の変数(容れ物)に格納されます。
この変数を置換後の文字列に配置すれば、キャプチャした文字列を展開することができます。

<font color=(.+)>(.+)</font>

•任意の1文字を表す.(ドット)

•1文字以上の繰り返しを表す+(プラス)

•文字列をキャプチャする()(カッコ
<font.+color=”([^”]*)[^>]*>([^<]*)</font>

[^>]*は、「>以外の文字の0個以上の繰り返し」という意味。
たとえば、<br>と<br />と<br/>。バラバラなとき、置換文字列をいずれかのパターンのbrタグにしてやれば、簡単に検索・置換を行えます。

正規表現の特殊文字をエスケープするpreg_quote()

正規表現で文字列の置換を行う場合、事前に特殊文字のエスケープを行わねばなりません。
そのために便利なPHPの関数がpreg_quote()です。

文章の先頭を意味する“^”や任意の一字を表す“.”のような特殊文字を、
通常の文字として置き換えたい場合、
あらかじめバックスラッシュを手前に書くことでエスケープしておかねば正しく動作してくれません。
preg_quote()はこのような場合に使います。

$str = ‘-._~%:/?#[]@!$&\'()*+,;=’;
$str = preg_quote( $str , ‘/’);
echo $str;// \-\._~%\:\/\?#\[\]@\!\$&’\(\)\*\+,;\=

preg_quote()の使い方は、第1引数にエスケープしたい文字列を渡します。
第2引数はオプションで、ここで指定した文字もデフォルトのものと共にエスケープしてくれます。
バッククオート“\”は正規表現の特殊文字ではないので、デフォルトでは置換されません。
しかし、バッククオート自体もエスケープの必要がありますので、preg_quote()を使う場合は必ず第2引数に’/’を渡すと考えておいた方が良いでしょう。

php 正規表現 パターンサンプル

PHP 正規表現サンプル集


URL

‘\b(https?|ftp|file)://[-A-Z0-9+&@#/%?=~_|!:,.;]*[-A-Z0-9+&@#/%=~_|]’

//URL を HTML のリンクに置き換える
preg_replace(‘\b(https?|ftp|file)://[-A-Z0-9+&@#/%?=~_|!:,.;]*[-A-Z0-9+&@#/%=~_|]’,
‘<a href=”\0″>\0</a>’, $text);


メールアドレス

新しい TLD への対応は随時行わないといけませんが、基本的な様式として参考にしてください。
尚、ドメイン名ではなく IP アドレスを利用したメールアドレスには対応していません。
また、大文字小文字を区別しないようにしてください。

//ドキュメント内のメールアドレスの検索に利用できます。
‘\b[A-Z0-9._%-]+@(?:[A-Z0-9-]+\.)+[A-Z]{2,4}\b’

//文字列全体がメールアドレスである場合にマッチします。
//入力検証に使う時は大文字小文字を区別しないと良いです。
‘^[A-Z0-9._%-]+@(?:[A-Z0-9-]+\.)+[A-Z]{2,4}$’

//特定の TLD
‘^[A-Z0-9._%-]+@[A-Z0-9.-]+\.(?:[A-Z]{2}|com|org|net|biz|info|name|aero|biz|info|jobs|museum|name)$’

//HTML リンク
‘\b(?:mailto:)?([A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,4})\b’


クレジットカード

//メジャーなクレジットカード
‘^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6011[0-9]{12}|3(?:0[0-5]|[68][0-9])[0-9]{11}|3[47][0-9]{13})$’

//アメリカンエクスプレス
‘^3[47][0-9]{13}$’

//ダイナーズクラブ
‘^3(?:0[0-5]|[68][0-9])[0-9]{11}$’

//ディスカバー
‘^6011[0-9]{12}$’

//マスターカード
‘^5[1-5][0-9]{14}$’

//VISA カード
‘^4[0-9]{12}(?:[0-9]{3})?$’


日付

2月31日のような意味的に不正な日付にはマッチしてしまうので注意してください。

//日付 d/m/yy と dd/mm/yyyy
//1/1/00 から 31/12/99 及び 01/01/1900 から 31/12/2099
‘\b(0?[1-9]|[12][0-9]|3[01])[- /.](0?[1-9]|1[012])[- /.](19|20)?[0-9]{2}\b’

//日付 dd/mm/yyyy
//01/01/1900 から 31/12/2099
‘(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.](19|20)[0-9]{2}’

//日付 m/d/y and mm/dd/yyyy
//1/1/99 から 12/31/99 and 01/01/1900 から 12/31/2099
//日付の区切りとしてダッシュ、空白、スラッシュ、ドットを受け入れます
‘\b(0?[1-9]|1[012])[- /.](0?[1-9]|[12][0-9]|3[01])[- /.](19|20)?[0-9]{2}\b’

//日付 mm/dd/yyyy
//01/01/1900 から 12/31/2099
‘(0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])[- /.](19|20)[0-9]{2}’

//日付 yy-m-d or yyyy-mm-dd
//00-1-1 から 99-12-31 及び 1900-01-01 から 2099-12-31
‘\b(19|20)?[0-9]{2}[- /.](0?[1-9]|1[012])[- /.](0?[1-9]|[12][0-9]|3[01])\b’

//日付 yyyy-mm-dd
//1900-01-01 から 2099-12-31
‘(19|20)[0-9]{2}[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])’


区切り

//二重引用符内ではないコンマをタブで置き換える
‘((?:”[^”,]*+”)|[^,]++)*+,’


HTML

//コメント
‘<!–.*?–>’

//HTML ファイル
‘<html>.*?<head>.*?<title>.*?</title>.*?</head>.*?<body[^>]*>.*?</body>.*?</html>’

//HTML タグのペア
//タグ名が第一キャプチャリンググループに入り、タグ内の文字列が第二のグループに入ります。
‘<([A-Z][A-Z0-9]*)[^>]*>(.*?)</\1>’


IP アドレス

//0.0.0.0 から 999.999.999.999
‘\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b’

//0.0.0.0 から 255.255.255.255
‘\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b’


//空白行 (空白文字も無し)
‘^$’

//空白行 (空白文字有りも可)
‘^[ \t]*$’

//空白行の改行
‘^\r?\n’

//空白行 (空白文字可) の改行
‘^[ \t]*$\r?\n’

//重複行
‘^(.*)(\r?\n\1)+$’


Numbers

//金額
//千の桁の区切りのカンマ及び小数点以下2桁可
‘\b[0-9]{1,3}(?:,?[0-9]{3})*(?:\.[0-9]{2})?\b’

//千の桁の区切りのカンマ可かつ小数点以下2桁必須
‘\b[0-9]{1,3}(?:,?[0-9]{3})*\.[0-9]{2}\b’

//符号はオプション。整数部分必須
‘[-+]?\b[0-9]+(\.[0-9]+)?\b’

//16進数
‘\b0[xX][0-9a-fA-F]+\b’

//千の桁区切りのカンマの挿入
//123456789.00 を 123,456,789.00 とする
‘(?<=[0-9])(?=(?:[0-9]{3})+(?![0-9]))’

//整数
‘\b\d+\b’

//符号はオプション。整数
‘[-+]?\b\d+\b’


パスワード

パスワードの複雑さのチェックを行います。

//6文字以上の文字、数字、下線、ハイフン
//最低でもひとつ大文字、ひとつ小文字、ひとつ数値を含む
‘\A(?=[-_a-zA-Z0-9]*?[A-Z])(?=[-_a-zA-Z0-9]*?[a-z])(?=[-_a-zA-Z0-9]*?[0-9])[-_a-zA-Z0-9]{6,}\z’

//6文字以上の文字を含むかチェック
//最低でもひとつ大文字、ひとつ小文字、ひとつ数値を含む
‘\A(?=[-_a-zA-Z0-9]*?[A-Z])(?=[-_a-zA-Z0-9]*?[a-z])(?=[-_a-zA-Z0-9]*?[0-9])\S{6,}\z’
ファイルパス

//Windows 用
‘\b[a-z]:\\[^/:*?”<>|\r\n]*’

//UNC 名
‘(?:(?#drive)\b[a-z]:|\\\\[a-z0-9]+)\\[^/:*?”<>|\r\n]*’


電話番号

//アメリカ
//3334445555, 333.444.5555, 333-444-5555, 333 444 5555, (333) 444 5555 にマッチ
//(333) 444-5555 の形に置換する
preg_replace(‘\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})’, ‘(\1) \2-\3’, $text);


エスケープ

//メタ文字をエスケープする
preg_replace(“[][{}()*+?.\\^$|]”, “\\$0”, $text);

SSN (ソーシャルセキュリティ番号)

‘\b[0-9]{3}-[0-9]{2}-[0-9]{4}\b’


トリム

//文字の後ろの空白をトリム (改行含む)
preg_replace(“\s+\z”, “”, $text);

//文字の前後の空白をトリム
preg_replace(“\A\s+|\s+\z”, “”, $text);

//文字の前の空白をトリム
preg_replace(“\A\s+”, “”, $text);

//各行の行末の空白をトリム
preg_replace(“[ \t]+$”, “”, $text);

//各行の前後の空白をトリム
preg_replace(“^[ \t]+|[ \t]+$”, “”, $text);

//各行の前方の空白をトリム
preg_replace(“^[ \t]+”, “”, $text);


住所

//アメリカの州コード
‘/\\b(?:A[KLRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])\\b/’

//アメリカ ZIP コード
‘\b[0-9]{5}(?:-[0-9]{4})?\b’
– See more at: http://keicode.com/cgi/php-regular-expression-samples.php#sthash.4FiF7Y0M.dpuf

PHPでコンテンツ取得の際に文字化けして、ブラウザに表示される

<<ケース>>UTF-8で統一、パスを以下で確認する場合

㋐「localhost/~」(ローカル開発環境)

㋑「~sakura.ne.jp/~」(レンタルサーバーにファイルアップロード)

【確認事項】
1)サーバーの設定がUTF-8になっているか
㋐XAMPPのコントロールパネルより、php.iniの設定が『UTF-8』で設定されているか確認する。

default_charset = “UTF-8”
mbstring.language = Japanese
mbstring.internal_encoding = UTF-8
mbstring.http_input = auto
mbstring.http_output = UTF-8
mbstring.encoding_translation = On
mbstring.detect_order = auto

㋑sakuraで『UTF-8』で設定されているか確認する。

 

2)phpファイルがコード『UTF-8』で保存されているか確認
※sublimetextでは、File>Set File Encoding To>コード選択でファイルのコード変換が可能

3)ブラウザのコードを確認
【IE】文字化けしているタブを開いて、表示>エンコード>UTF-8で設定可能
【GoogleChrome】設定>ウェブコンテンツのフォントをカスタマイズ>エンコードで『UTF-8』を選択

 

 

以上、確認する事で、問題は解消!!

preg_match 、preg_match_all (正規表現にマッチしたデータ抽出)

(PHP 4, PHP 5)

preg_match — 正規表現によるマッチングを行う
preg_match_all — 繰り返し正規表現検索を行う

【構文】
preg_match_all
($pattern , $subject [, $matches [, $flags = 0 [, $offset ]]]  )

<<引数>>
$pattern = ‘/^def/’;  //検索パターン
$subject “abcdef”; //検索対象文字列
$matches          //検索結果を代入する器
$flags    PREG_PATTERN_ORDER , PREG_SET_ORDER ,      //
$offset

 

http://frozentuna.hatenablog.jp/entry/2012/06/27/223633
preg_match関数のパターン変数について
$pattern = “/ ~~/”

のように/をデリミタに使っていたが、実は括弧とか記号でもいいらしい。

・サブパターンの有効活用

PHPの正規表現において( )で囲われた部分はサブパターンとして機能する。

preg_match関数ではマッチした部分文字列を保存すると、サブパターンの部分も保存してくれる。

例)<p>タグで囲われたテキストを抽出する

$text = “<p>ここを取り出したい</p>”;

$pattern = “{<p>(.*)<\/p>}”;

preg_match($pattern,$text,$match);

こうすると一致結果が$matchに入り、

$match[0] = “<p>ここを取り出したい</p>”

$match[1] = “ここを取り出したい”

となる。

一気にタグを除去した情報まで手に入れられるのでうまく使いたいところ。

require文とinclude文

require文やinclude文などは、別ファイルにまとめた関数やファイル、プログラムを読み込む時に使用します。

【1】require文
require文は、スクリプトの実行に先立ち、指定したファイルの内容に置き換えられます。
ループ処理の中に置いて、毎回異なるファイルを読み込むことはできません

■require()関数で「city.php」を読み込み
<?php
require( “city.php” );
echo city;
?>

【2】include文
include文は、スクリプトの実行に先立ち、指定したファイルの内容に置き換えられます。
ループ処理の中にinclude文を置いて、毎回異なるファイルを読み込むことができます。

■include()関数で「city1.php」「city2.php」「city3.php」を読み込み
<?php
for( $i=1 ; $i<=3 ; $i++ ) {
include( “city” . $i . “.php” );
}

echo $city1;
echo $city2;
echo $city3;
?>

【3】require_once文
require_once文は、require()関数と同様に、スクリプト内で別ファイルを読み込むことができます。
require()関数と異なる点は、require()関数は外部ファイルを取り込む回数に制限がないのに対して、
require_once()関数は外部ファイルを1回だけ取り込みます。
【4】include_once文
include_once文は、include()関数と同様に、スクリプト内で別ファイルを読み込むことができます。
include_once()関数も、require()関数とrequire_once()関数との違いと同様に、
include_once()関数は外部ファイルを1回だけ取り込みます。

【5】require文とinclude文の違い
require()とinclude()は、ループとエラーの扱い方を除けば、その動作は全く同じです。
require文は、ループ処理の中に置いて、毎回異なるファイルを読み込むことはできませんが、include文は可能です。
またエラーについて、require()は「Fatal Error」となり処理を停止しますが、 include()は「Warning」を出力しながら、
読み込むべきファイルが存在しない場合も処理を続行します。
両者の違いをしっかり把握したうえで、機能に沿った方を使いましょう。

require文とinclude文の違い require文 include文
ループ処理での利用 不可能 可能
エラー処理 停止 続行