
とあるサイトで、
「URL からドメイン名を得る」という項目があったのでマネして
やってみたらうまくいきました。しかし正規表現パターンの意味は
理解できませんでしたので理解できなかった部分だけをのせたスクリプトを以下にまとめました。
<?php
// まずUPLからホスト名を得る
preg_match('@^(?:http://)?([^/]+)@i',
"http://www.nantoka.com/index.html", $matches);
$zenbu=$matches[0];
$host = $matches[1];
$saigo=$matches[2];
/*必要なのはホスト名だけですが、$matches[0]や$matches[2]には
どんな文字列が格納されるか気になって出力することにしました*/
print($zenbu);
print("<br/>");
print($host);
print("<br/>");
print($saigo);
print("<br/>");
?>
これを実行した結果は、
$zenbuが「http://www.nantoka.com」で、
$hostが「www.nantoka.com」で、
$saigoがなにもなしでした。
このスクリプトでわからない部分は、'@^(?:http://)?([^/]+)@i'の部分と、$host = $matches[1];の部分です。
まず正規表現パターンの最初のアットマークの後ろの^は「次の文字列からはじまる」と解釈しました。
最後のアットマークの後ろのiは、「大文字と小文字を区別しない」という意味だと解釈しました。
カッコで囲まれている(?:http://)と、([^/]+)は、サブマッチパターン
だと思いました。
$matches[0]には、"http://www.nantoka.com/index.html"の
中で'@^(?:http://)?([^/]+)@i'に当てはまるもの全体が格納され、
$matches[1]には、(?:http://)に当てはまるもの、
$matches[2]には、([^/]+)に当てはまるものが格納されると考えました。
[^/]+は、「スラッシュを含まない文字が1文字以上」と解釈しました。
ただ、その他の事については考えましたがよくわからず、
特になんで(?:http://)にあたるものが「www.nantoka.com」
になるのかさっぱりわかりません。
(?:http://)の中にあるhttp://の前の?:が一体何なのか、
(?:http://)と([^/]+)の間にある?は何なのか、
両端のアットマークは何なのか(マッチ演算子かと思って
スラッシュに置き換えて実行してみたらエラーになりました。)
うまく説明できませんがとにかくその辺のことがよくわかりませんでした。どなたか教えていただけませんか。
A 回答 (3件)
- 最新から表示
- 回答順に表示
No.3
- 回答日時:
と、その他の部分も補足します。
まず、@ですが、正規表現のマッチングの場合、マッチング対象を囲みます。
通常は、「/」を使うのですが、今回のマッチング文字列の中に「/」が含まれているため、代替として「@」を使っているのだと思います。
マッチ演算子として、「/」に戻した場合、内部の「http://」の「/」を¥マークでエスケープしないとエラーになってしまうと思います。
つづいて、(?:http://)の後の?ですが、これは「この?の前にあるブロックが、0~1回出てくること」という条件になります。
なので、http://http://aaaという文字列を入れた場合、http://を1回分だけよりわける、ということが出来るようになります。
エラーの詳細まで教えていただき感謝しています。
http://の後の?についても確かめてみました、
(なんのためにhttp://が2つもあったりhttp://がなかったりするのか
はよくわかりませんが、検索したら実際にそういうものがありますね。)
No.2
- 回答日時:
@はここでは、正規表現の始まりと終わりを示すものとして使われています。
通常この目的には '/' が使われることが多いのですが、今回マッチングに
使用するパターンに '/' が複数含まれているのでエスケープのバックスラッシュを
多用することによって見づらくなるのを避けるために'@' を使用したのでしょう。
$matches[0], $matches[1], $matches[2], ... ですが
0 → パターンにマッチした全体
1 → 1番目のサブパターンに捕獲された部分文字列
2 → 2番目のサブパターンに捕獲された部分文字列
となります。ここで、(?: ) と ( ) とは違うものだということに注意してください。
(?: ) によりグループ化された場合、捕獲はなされません。つまり、
> $matches[1]には、(?:?http://)?に当てはまるもの、
> $matches[2]には、([^/]+)に当てはまるものが格納されると考えました。
これがひとつずれます。$matches[1] には ([^/]+)によって捕獲されたものであり、
このパターンには捕獲を行うグループ化はひとつしかありませんので、
$matches[2]は常に空になります。
順番が前後しましたが、'(?:' の三文字で捕獲をしないグループ化を表す
メタ文字になってます。ですので '?:' それ自体に意味はありません。
No.1
- 回答日時:
まさにossuさんがわからない、といっていた「?:」がこの部分の肝となります。
(?:~~~)とすると、この括弧の部分を検索時のマッチ対象から外すことが出来るようになります。
このため、$matches[1]に本来、$matches[2]に入る内容が入ってくることになります。
詳しくは、PHPマニュアルをご覧下さい。
参考URL:http://search.net-newbie.com/php/reference.pcre. …
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
正規表現で、半角大文字と半角...
-
PHPで<a>タグ内からURLと文字を...
-
正規表現での英字+ハイフンの...
-
VBAを使ってHTMLソースから特定...
-
JBScriptの正規表現のマッチ文...
-
VBAのコマンドボタンの文字列の...
-
文字化け変換方法
-
Excel関数「COUNTIF」で”文字”...
-
全角括弧と全角読点の間隔を狭...
-
(UWSC)1行が長いので、途中改行...
-
特定の文字を簡単な操作で半角...
-
文字の入力で横バー上段、中断...
-
ダイアログにおける改行
-
mb_send_mailの2重投稿を防止し...
-
JAVA System.out.println の ...
-
awkで改行を除いて文字列を抜き...
-
sendmailの改行について
-
【VB6】項目内に改行コードを含...
-
エスケープ文字の復帰(¥r)と...
-
文字列中の両丸括弧を取り除くV...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
、"(ダブルクォーテーション)...
-
正規表現で、半角大文字と半角...
-
PHPで変数から1行目だけを取得...
-
PHPで<a>タグ内からURLと文字を...
-
携帯アドレスの正規表現
-
VBAを使ってHTMLソースから特定...
-
正規表現について
-
preg_matchでエラーが出ます。
-
switchの大量分岐の高速化
-
1ファイルから項目を正規表現で...
-
変数に指定文字列が含まれると...
-
電話番号のチェック ハイフン...
-
複雑な/による文字列の分割につ...
-
正規表現で「0」のみ抽出
-
サイトが移動しました(301)が...
-
Excelで数字のみを2倍3倍にする...
-
Smartyで部分一致
-
PHPの正規表現について
-
PHPで あるフォルダ内の、特定...
-
正規表現 先頭一桁をマッチさせ...
おすすめ情報