PHPについて質問です。


下記のような複数のURLがあるとします。
http://hatena.ne.jp/aaa/dddd/
http://hatena.ne.jp/bbb/fff/
http://hatena.ne.jp/ccc/dddd/
http://hatena.ne.jp/aaa2/fff/
http://google.ne.jp/aaa2/dddd/

「hatena.ne.jp」というドメインを持つURLの中から「aaa」という
文字列があるURLだけを取り出すというスクリプトを作成してください。
つまり、下記のURLだけが取り出されるというものです。
http://hatena.ne.jp/aaa/dddd/
http://hatena.ne.jp/aaa2/fff/

質問者はまだPHPの学習を初めて間もない初心者なので、
自分のやりたいことをうまく質問することもままなりません。
不明瞭な場合はその旨コメントをいただければ幸いです。
また、回答は初心者にもわかるようご配慮くださいますようお願いします。

いろんなパターンを知りたいのでたくさんの方からの
ご回答をお待ちしています。

以上、よろしくお願いします。


回答の条件
  • URL必須
  • 1人2回まで
  • 登録:2008/02/13 02:36:01
  • 終了:2008/02/13 11:49:42

回答(3件)

id:hatettyo No.1

hatettyo回答回数23ベストアンサー獲得回数22008/02/13 03:20:57

ポイント12pt

複数のURLが配列に入っていると仮定したスクリプトは下記の通りです。

わかりやすくする為、ちょっと遠まわしな表現が多いです。

<?php
$urls = array();
$urls[] = "http://hatena.ne.jp/aaa/dddd/":
$urls[] = "http://hatena.ne.jp/bbb/fff/":
$urls[] = "http://hatena.ne.jp/ccc/dddd/":
$urls[] = "http://hatena.ne.jp/aaa2/fff/":
$urls[] = "http://google.ne.jp/aaa2/dddd/":

foreach($urls as $value){
    //条件に合ったドメインか調べます。
    $domain_flag = eregi("hatena.ne.jp",$value);
    if($domain_flag == TRUE){
            //条件の文字列が入っているか調べます。
            $sring_flag = eregi("aaa",$value);
            if($string_flag == TRUE){
                 echo $value;
            }
    }
}

?>

dummy

http://hatena.ne.jp/

id:taroemon

再度のご回答ありがとうございます。

本当に助かります。


そのままコピペしてもエラーが出るようですが・・・。

自分でもどうしてよいかわかりません。

またお時間のあるときにご回答ください。


-----------------------------------------------------

質問文訂正

-----------------------------------------------------

勘違いをしていました。

「hatena.ne.jp」というドメインを持つURLの中から「aaa」という

文字列がないものを全て削除するというスクリプトを作成してください。

つまり、下記のURLだけが取り出されるというものです。

http://hatena.ne.jp/aaa/dddd/ (hatena.ne.jpだが「aaa」を含んでるので残す)

http://hatena.ne.jp/aaa2/fff/ (hatena.ne.jpだが「aaa」を含んでるので残す)

http://google.ne.jp/aaa2/dddd/ (他のドメインはそのまま残しておいてください。)

お騒がせして済みません。

今後ご回答いただく皆さんにはこのスクリプトを作成していただくようお願いします。

2008/02/13 04:42:09
id:hatettyo No.2

hatettyo回答回数23ベストアンサー獲得回数22008/02/13 06:43:27

ポイント34pt

すみません。さっきのスクリプト文法ミスが多々ありました。

正しくは下記スクリプトです。

<?php
$urls = array();
$urls[] = "http://hatena.ne.jp/aaa/dddd/";
$urls[] = "http://hatena.ne.jp/bbb/fff/";
$urls[] = "http://hatena.ne.jp/ccc/dddd/";
$urls[] = "http://hatena.ne.jp/aaa2/fff/";
$urls[] = "http://google.ne.jp/aaa2/dddd/";

foreach($urls as $value){
//条件に合ったドメインか調べます。
$domain_flag = eregi("hatena.ne.jp",$value);
if($domain_flag == TRUE){
//条件の文字列が入っているか調べます。
$string_flag = eregi("aaa",$value);
if($string_flag == TRUE){
echo $value;
}
}
}

?>

新たな質問内容についてですが

<?php
$urls = array();
$urls[] = "http://hatena.ne.jp/aaa/dddd/";
$urls[] = "http://hatena.ne.jp/bbb/fff/";
$urls[] = "http://hatena.ne.jp/ccc/dddd/";
$urls[] = "http://hatena.ne.jp/aaa2/fff/";
$urls[] = "http://google.ne.jp/aaa2/dddd/";

foreach($urls as $value){
    //条件に合ったドメインか調べます。
     //hatena.ne.jpが含まれている場合は$string_flagにTRUEが入る
    $domain_flag = eregi("hatena.ne.jp",$value);
    //条件の文字列が入っているか調べます。
     //aaaが含まれていない場合は$string_flagにFALSEが入る
     $string_flag = eregi("aaa",$value);

    if(($domain_flag == TRUE)&&($string_flag == FALSE)){
        //ループを飛ばす
        continue;
    }
    echo $value."<br>";
}
?>


参考URL

http://jp2.php.net/manual/ja/function.eregi.php

id:taroemon

再度のご回答ありがとうございます。

3日間かかってできなかったことがようやくできました。感動です。

2008/02/13 11:29:43
id:tezcello No.3

tezcello回答回数460ベストアンサー獲得回数692008/02/13 10:32:45

ポイント34pt

http://hatena.ne.jp/aaa/dddd/ (hatena.ne.jpだが「aaa」を含んでるので残す)

http://hatena.ne.jp/aaa2/fff/ (hatena.ne.jpだが「aaa」を含んでるので残す)

http://google.ne.jp/aaa2/dddd/ (他のドメインはそのまま残しておいてください。)

というように、考え方がわかっているなら、それをそのままスクリプトにすればいいんです。

冗長なものになってしまい易いですが、そうやって慣れていくんです。


先ず、複数URLがありますが、それぞれについて調べるのですから、一旦配列に収めておきます。

結果を収める配列も用意しておきます。

  それぞれについて同じ検査を繰り返す という手法を使いたい為です。

検査をする部分は、

指定したドメインであるかを調べて、その結果で処理を分ける

  指定したドメイン(hatena.ne.jp)である場合

    指定した文字列(aaa)が含まれていれば結果配列に入れる

    この時、aaa がどこにあってもよい場合と、指定した所(例えばドメイン直下)の場合で

    調べ方が異なります。

  指定したドメインで無い場合

    結果配列に入れる

という感じです。

これをスクリプトに換えていきます。

$string = array(
	'http://hatena.ne.jp/aaa/dddd/',
	'http://hatena.ne.jp/bbb/fff/',
	'http://hatena.ne.jp/ccc/dddd/',
	'http://hatena.ne.jp/aaa2/fff/',
	'http://hatena.ne.jp/ccc/aaa/',
	'http://google.ne.jp/aaa2/dddd/'
	);

$result = array();	// 結果配列

$domain = 'http://hatena.ne.jp/';
$keyword = 'aaa';

// preg系の正規表現内では/等をエスケープしておかなければならない
// $domain に/.を含む文字列を指定したので追加した
// $keyword にはこの例では不要だが、念の為
$domain = preg_quote($domain, '/');
$keyword = preg_quote($keyword, '/');

foreach($string as $str){
	$f_domain = preg_match("/$domain/", $str);	// どこにキーワードがあってもよい場合
	if ($f_domain){
		$f_keyword = preg_match("/$keyword/", $str);
		if ($f_keyword){
			$result[] = $str;
		}
	}else{
		$result[] = $str;
	}
}

var_dump($result);

結果は

array(4) {

[0]=>

string(29) "http://hatena.ne.jp/aaa/dddd/"

[1]=>

string(29) "http://hatena.ne.jp/aaa2/fff/"

[2]=>

string(28) "http://hatena.ne.jp/ccc/aaa/"

[3]=>

string(30) "http://google.ne.jp/aaa2/dddd/"

}

最初はこんな感じで、徐々に整理していくとよいのではないでしょうか?

例えば、わざわざ変数($f_domain, $f_keyword)に代入しなくてもよいでしょうし、

if の辺りはもっと単純化できるはずです。


URLが必要との事なので、マニュアルを。

http://jp.php.net/manual/ja/function.preg-match.php

http://jp.php.net/manual/ja/function.preg-quote.php

id:taroemon

非常に丁寧に解説していただいてありがとうます。

おかげでだいぶ理解できました。

2008/02/13 11:48:48
  • id:tobeoscontinue
    >下記のような複数のURLがあるとします。
    同じ様なものが複数ある場合は配列にするのが定石です。
    ので複数のURLは下記のように表せられます。
    $urls = array(
    "http://hatena.ne.jp/aaa/dddd/",
    "http://hatena.ne.jp/bbb/fff/",
    "http://hatena.ne.jp/ccc/dddd/",
    "http://hatena.ne.jp/aaa2/fff/",
    "http://google.ne.jp/aaa2/dddd/"
    );

    >あるURLだけを取り出すというスクリプトを作成してください。
    これを言い替えると配列をあるURLだけの配列にするとなります。
    こういった場合http://q.hatena.ne.jp/1202569301にあった
    [http://jp.php.net/manual/ja/function.array-filter.php:array_filter()]が一番機能的に近いです。

    $select = array_filter($urls, "どれを取り出すかの関数名");
    これで$selectにはあるURLだけの配列となります。


    残りは"どれを取り出すかの関数"(コールバック関数)を作るだけです。
    コールバック関数の名前をhatena_not_aaaとするとコールバック関数は

    function hatena_not_aaa($var) {
    return TRUE あるいは FALSE;
    }

    となります。$varにはarray_filterによって$urlsの配列要素が一個づつ順に渡されます。
    このコールバック関数ではTRUEを返すと取り出だされ、FALSEを返すと捨ててしまう(何もしない)と決められています。
    のであとは取り出だすか取り出ださないかのTRUEかFALSEを決める方法を示すだけです。


    >「hatena.ne.jp」というドメインを持つURLの中から「aaa」という文字列がないものを全て削除する
    これを言い替えると「hatena.ne.jp」という文字列があってかつ「aaa」という文字列が無いならFALSEを返す
    となります。ある文字列があるかどうかを調べる方法はいくつかありますが今回は単純にstrpos()を使いました。
    strpos()は文字列があればその文字位置を返します。が使用にはPHP特有の注意が必要です。


    更に言い替えます
    !(「hatena.ne.jp」という文字列があってかつ「aaa」という文字列が無い)
    とします。!は反転で()内がTRUEならFALSEになります。
    「hatena.ne.jp」という文字列があっては=>strpos($var,"hatena.ne.jp")
    かつは=> &&
    「aaa」という文字列が無いは=>(strpos($var, "aaa") === FALSE)
    となります。===は重要です。==ではいけません。
    よって条件は

    !(strpos($var, "hatena.ne.jp") && (strpos($var, "aaa") === FALSE));

    となります。全体としては

    <?php
    $urls = array(
    "http://hatena.ne.jp/aaa/dddd/",
    "http://hatena.ne.jp/bbb/fff/",
    "http://hatena.ne.jp/ccc/dddd/",
    "http://hatena.ne.jp/aaa2/fff/",
    "http://google.ne.jp/aaa2/dddd/"
    );

    function hatena_not_aaa($var) {
    return !(strpos($var, "hatena.ne.jp") && (strpos($var, "aaa") === FALSE));
    }

    $select = array_filter($urls, "hatena_not_aaa");

    print_r($select);
    ?>

    ただ文字が表れる位置は考慮していません。
    "aaa/hatena.ne.jp"のような文字列を区別しませんし、"hatena.ne.jp/bbb"のようにhatena.ne.jpが先頭から始まっている場合は削除しません。厳密にする必要があるのであれば別の比較方法を検討する必要がありますが、他の部分はそのままでいいでしょう。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません