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

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

新規登録して質問してみよう
ただいま回答率
85.50%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

Q&A

解決済

3回答

2458閲覧

指定した範囲内の数字とファイル名の文字列が部分一致するファイルを一覧として表示したい

Webtuuuu

総合スコア30

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

0グッド

0クリップ

投稿2019/04/11 08:17

編集2019/04/11 10:23

##やりたいこと
指定した範囲内の数字と、ファイル名の文字列が部分一致するファイルを一覧として表示したい

###以下例
10~20のいずれかの文字列をファイル名に含むファイルを一覧として出力したい場合

###フォルダにあるファイル(一例)
5-test.txt
11-test.txt
15-test.txt
18-test.txt
20-test.txt
21-test.txt

###上記フォルダから欲しいファイル
11-test.txt
15-test.txt
18-test.txt
20-test.txt

###変数に欲しい範囲の数値を指定(変動)
$start = 10;
$end = 20;

この場合の10~20の数値部分が一致するファイルだけ出力

##問題点
今現状だと「10-test.txt」だけを出力するようになっている

php

1if ( strpos( $file, $start ) === false ) { 2 //無かった場合はなにもしない 3} else { 4 echo $file . " (" . $path . ")" . "\n" ; 5}

これを「10~20で一致したもの」に変更したいが、書き方がわからない


現状の全体のphpは以下

php

1$start = $_POST['request01']; // ajaxで受け取った最小値 2$end = $_POST['request02']; // ajaxで受け取った最大値 3$dir = '../hoge/'; // ディレクトリのパス 4 5$check_dirs = [ $dir ] ; 6$file_paths = [] ; 7 8 while( $check_dirs ) { 9 $dir_path = $check_dirs[0] ; 10 11 if( is_dir ( $dir_path ) && $handle = opendir ( $dir_path ) ) { 12 while( ( $file = readdir ( $handle ) ) !== false ) { 13 if( in_array ( $file, [ ".", ".." ] ) !== false ) continue ; 14 $path = rtrim ( $dir_path, "/" ) . "/" . $file ; 15 16 if ( filetype ( $path ) === "dir" ) { 17 $check_dirs[] = $path ; 18 } else { 19 // 文字列が含まれるかどうかチェック 20 if ( strpos( $file, $start ) === false ) { 21 //無かった場合はなにもしない 22 } else { 23 echo $file . " (" . $path . ")" . "\n" ; 24 } 25 } 26 } 27 } 28 29 array_shift( $check_dirs ) ; 30 } 31 print_r($file);

参考にしたコード
※以下サイトの下部にあるデモコード(再帰的に取得の部分)
https://lab.syncer.jp/Web/PHP/Snippet/16/


※補足
上記は一例のため1020としているが、実際は10万ファイル以上の中からふるいにかけるため、
実際の使用の際には「32000
39000」のような変数になる
また、今回はindex.htmlにinputタグを2個設け、jquery・Ajaxを使用してphpに指定値を送り
変数の$startと$endに格納している。

※追記
コメントいただいたため追記します。

>10万ファイル以上の中からふるいにかける
この10万ファイルは様々な階層にフォルダ分けされています。
そのため参考サイトの「再帰的に取得」を使用しています。

さらに、今回の例ではファイル名の形式は
〇〇-test.txtしかありませんでしたが実際には拡張子は様々で、
・test-〇〇.jpg
・hogehoge〇〇hoge.gif
など数値は必ず入っているものの形式がまちまちです。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

こんな感じ

php

1<?PHP 2$start=filter_input(INPUT_POST,"request01",FILTER_VALIDATE_INT); 3$end=filter_input(INPUT_POST,"request02",FILTER_VALIDATE_INT); 4 5if(!is_null($start) and $start!==false and !is_null($end) and $end!==false){ 6 $a=glob("*-test.txt"); 7 //$a=["5-test.txt","11-test.txt","15-test.txt","18-test.txt","20-test.txt","21-test.txt"]; 8 $a=array_filter($a,function($x) use($start,$end){ 9 return preg_match("/^(\d+?)-test.txt$/",$x,$m) and $m[1]>=$start and $m[1]<=$end; 10 }); 11 print_r($a); 12} 13?> 14<form method="post"> 15start:<input type="text" name="request01" value="10"><br> 16end:<input type="text" name="request02" value="20"><br> 17<input type="submit" value="send"> 18</form>

フォルダ内に入っているファイル名の形式は〇-test.txtだけではなく拡張子も様々で

数字の記入位置もまばらです。

となるとglobのワイルドカードは調整ですね
たとえば数字を含むファイルならこんな感じ

PHP

1$a=glob('*[0-9]*');

その上で

PHP

1 return preg_match("/(\d+?)$/",$x,$m) and $m[1]>=$start and $m[1]<=$end;

で拾ってください

ただし「10-15.txt」的なファイルは11から20の間に入るのか否か微妙です

規模が大きいならファイルをアップするときにRDBに登録して
検索はオーバーヘッドの大きいファイルシステムではなくSQLに任せるのも
検討の余地があります

投稿2019/04/11 08:53

編集2019/04/11 10:33
yambejp

総合スコア114583

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yambejp

2019/04/11 09:21

フォルダ分けせずに10万ファイルも置いてあると ファイルシステム的に微妙です lsやrmでワイルドカードがちゃんと機能しなかったりするかも
Webtuuuu

2019/04/11 10:17

コメントいただきありがとうございます。 >フォルダ分けせずに10万ファイルも置いてある すみません、こちら説明不足でした。 こちら実際のところはフォルダ分けはされており、 Aというフォルダの中に 5-test.txt 11-test.txt 14-test.txt ・・・ となっており、Bというフォルダの中にも 6-test.txt 8-test.txt 10-test.txt ・・・ と、フォルダを含めこれがたくさんある状態です。 そのため、質問エリア内に記載した参考にしたサイトの「再帰的に取得」を使っている次第です。 また、こちらも説明不足でしたが、 フォルダ内に入っているファイル名の形式は〇-test.txtだけではなく拡張子も様々で 数字の記入位置もまばらです。
yambejp

2019/04/11 10:31

ちょっと後出しの条件が多すぎるので もう少し仕様を固めたほうがいいでしょう
guest

0

ベストアンサー

// 文字列が含まれるかどうかチェック

この部分を、発想変えて以下のようにすれば簡単じゃないですか?

  1. ファイル名($file)の文字列から数字部分(先頭から-の直前まで)を取り出す。
  2. 1で取り出した数字部分を数値にする
  3. if 文で入力した範囲にあるかを判定する

投稿2019/04/11 08:30

Y.H.

総合スコア7914

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Webtuuuu

2019/04/11 10:11

コメントいただきありがとうございます。 すみませんPHPに関してかなり知見不足でして… いただいたコメントを参考に書き換えて試してみます。 ありがとうございます。
guest

0

ベストアンサーの方の案をもとに書き換えて実装できました。

↓元のソース(一部抜粋)

php

1if ( strpos( $file, $start ) === false ) { 2 //無かった場合はなにもしない 3} else { 4 echo $file . " (" . $path . ")" . "\n" ; 5}

↓書き換え後のソース(一部抜粋)

php

1 2$file = substr($file, 0, 6); //取得したファイル名の頭から6桁を指定 3$number = preg_replace('/[^0-9]/', '', $file); //数値のみに変換 4 5// $startより多く$endより小さい数値の時 6if ( $number <= $start || $number >= $end ) { 7 //数値が範囲外の場合なにもしない 8} else { 9 echo $file . " (" . $path . ")" . "\n" ; 10}

しかしながら他の方からも回答があった通り後出しの要件が多く
>数字の記入位置もまばら
この部分のみ対応できていないのですがいったんこの質問においては解決とさせていただきます。

投稿2019/04/13 10:49

Webtuuuu

総合スコア30

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問