質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.34%

[PHP]要素に空白があった場合にVar_dumpに出力させない

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 987

maguroyamiy

score 10

前提・実現したいこと

初心者です。
PHPでgoutteを使ってスクレイピングをしています。

サイトから上位20人の名前と時間を取得しています。
全てが記載されているわけではなく空白もあります。

そこで題の通り、取得してきた名前と時間の両方が空(無し)だった場合、
画像のようにarray[]=>から消したいのです。
正確に言えば、空欄があれば配列に出さない でしょうか。

まだ不慣れですがよろしくお願いします。

イメージ説明

該当のソースコード

for ($i = 0; $i < 20; $i++){

    //名
    $name = $crawler->Filter('tbody')->Filter('tr')->eq($i)->Filter('td')->eq(0)->text();

    //時間
    $time = $crawler->Filter('tbody')->Filter('tr')->eq($i)->Filter('td')->eq(3)->text();

    $list[] = array(array(trim($name),trim($time))
                    );
}

echo var_dump($list);

追伸

trimで空白を消してから配列にしているのですが、
「文字が無い場合」('')を非表示に出来ませんか?

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • kei344

    2016/08/02 17:35

    コードはコードブロックで囲んでいただけませんか? ```(バッククオート3つ)で囲み、前後に改行をいれるか、コードを選択して「</>」ボタンを押すとコードブロックになります。

    キャンセル

  • maguroyamiy

    2016/08/02 18:02

    修正しました。

    キャンセル

回答 3

+4

空白が半角であることを前提で。

for ($i = 0; $i < 20; $i++) {

    //名
    $name = $crawler->Filter('tbody')->Filter('tr')->eq($i)->Filter('td')->eq(0)->text();

    //時間
    $time = $crawler->Filter('tbody')->Filter('tr')->eq($i)->Filter('td')->eq(3)->text();

    if (!empty(trim($name)) && !empty(trim($time))) {
        $list[] = array(
            array(
                $name
                , $time
            )
        );
    }
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+3

マルチポスト


コード若干変わってるみたいなので書き直しますね

$list = $crawler->filterXPath('//tr[
    position() <= 20 and 
    normalize-space(.//td[1]) != "" and
    normalize-space(.//td[4]) != ""
]')->each(function ($tr) {
    return [
        trim($tr->filter('td')->eq(0)->text()),
        trim($tr->filter('td')->eq(3)->text()),
    ];
});

var_dump($list);

 補足

(冗長なので勝手に修正しましたが) もし希望されているように2重の配列構造がよければ,以下のようにします.

$list = $crawler->filterXPath('//tr[
    position() <= 20 and 
    normalize-space(.//td[1]) != "" and
    normalize-space(.//td[4]) != ""
]')->each(function ($tr) {
    return [[
        trim($tr->filter('td')->eq(0)->text()),
        trim($tr->filter('td')->eq(3)->text()),
    ]];
});

var_dump($list);

なお,

上記で提示されているプルリクエストが採用されれば,今後以下のように書けるようになる可能性があります.

$list = $crawler->filterXPath('//tr[
    position() <= 20 and 
    normalize-space(.//td[1]) != "" and
    normalize-space(.//td[4]) != ""
]')->each(function ($tr) {
    return [
        $tr->evaluate('normalize-space(.//td[1])')[0],
        $tr->evaluate('normalize-space(.//td[4])')[0],
    ];
});

var_dump($list);

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

checkベストアンサー

0

$listを得た後フィルターしてください

var_dump(array_filter($list,function($a){
  $pattern="/^ *$/";
  if(preg_match($pattern,$a[0]) and preg_match($pattern,$a[1])){
    return false;
  }else{
    return true;
  }
})
);


どちらかが空白だけの場合は上記、両方とも空白だけの場合はpreg_matchの間をorにしてください

 修正

すみません、構造を見間違えていました

var_dump(array_filter($list,function($a){
  $pattern="/^ *$/";
  if(preg_match($pattern,$a[0][0]) and preg_match($pattern,$a[0][1])){
    return false;
  }else{
    return true;
  }
})
);

 追記

抜け番を埋めるのはarray_merge()がよく使われます。
一度別の配列にうけてください

$mylist=array_filter($list,function($a){
  $pattern="/^ *$/";
  if(preg_match($pattern,$a[0][0]) and preg_match($pattern,$a[0][1])){
    return false;
  }else{
    return true;
  }
});
$mylist=array_merge($mylist);
var_dump($mylist);

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/08/02 20:39

    あら、抜け番を希望しているのかと思いました。
    修正を上げておきます

    キャンセル

  • 2016/08/02 20:53

    >> 抜け番を埋めるのはarray_merge()がよく使われます。

    いやいやarray_valuesでしょう…
    (array_mergeは用途が違いますがarray_valuesはそれ専用の関数です)

    キャンセル

  • 2016/08/02 21:04 編集

    【どちらかが埋まっていれば残す (1)】
    $list = array_values(array_filter($list, function ($a) {
        return !empty(array_filter(array_map('trim', $a[0]), 'strlen'));
    }));

    【どちらかが埋まっていれば残す (2)】
    $list = array_values(array_filter($list, function ($a) {
        return !empty(preg_grep('/\A\s*\z/', $a[0], PREG_GREP_INVERT));
    }));

    【両方が埋まっている場合のみ残す】
    $list = array_values(array_filter($list, function ($a) {
        return empty(preg_grep('/\A\s*\z/', $a[0]));
    }));

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.34%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る