PHPの記述方法について教えて下さい。

〇ファイル4つ(1)data.txt(2)koukoh.txt(3)daigaku.txt(4)shakaijin.txt
それぞれのファイルパスはhttp://xxxxx.jp/xxxxx.txt。data.txtのパターン:"/^(\d+\s.+?\s)(.*?)(※①)(@.*?)(\n|$)/";
■要望
「data.txt」の中で、上記※①の箇所に高卒、大卒、高社、大社が入っている行に対して行末に、高卒がある場合は「@→高校名→」。大卒がある場合は「@→高校名→大学名→」。高社がある場合は「@→高校名→会社名→」。大社がある場合は「@→高校名→大学名→会社名→」という文字列を追加。上記に該当しない行はそのまま何も追加せずに表示する。※data.txtは英字、数字、日本語が混在。※高校名、大学名、会社名は(2)~(4)の行ごとに格納されている〇〇名をランダムに選択したい。どうかご教授お願い申し上げます。

回答の条件
  • 1人10回まで
  • 13歳以上
  • 登録:2010/03/14 11:12:47
  • 終了:2010/03/21 11:15:02

回答(4件)

id:tezcello No.1

tezcello回答回数459ベストアンサー獲得回数692010/03/14 23:01:17

ポイント23pt

/^(\d+\s.+?\s)(.*?)(※①)(@.*?)(\n|$)/

は、@ の直前にある「※①」の最後のものという事のようですが、

/([高大][卒社])@/u で代用出来そうな気がします。

/([高大][卒社])@.*?$/u の方がより正確でしょうけど。

$data = file('http://xxxxx.jp/data.txt', FILE_IGNORE_NEW_LINES);
$koukoh = file('http://xxxxx.jp/koukoh.txt', FILE_IGNORE_NEW_LINES);
$daigaku = file('http://xxxxx.jp/daigaku.txt', FILE_IGNORE_NEW_LINES);
$shakaijin = file('http://xxxxx.jp/shakaijin.txt', FILE_IGNORE_NEW_LINES);

foreach($data as $val){
  $addval = '';
  if (preg_match('/([高大])([卒社])@/u', $val, $mch)){
    $addval = '→'.array_rand($koukoh);
    if ($mch[1] == '大') $addval .= '→'.array_rand($daigaku);
    if ($mch[2] == '社') $addval .= '→'.array_rand($shakaijin);
  }
  print $val.$addval."\n"; // "\n" ではなく "<br>\n" とすればブラウザ上でも改行してくれます
}
id:himedaisan

$data = file('http://xxxxx.jp/data.txt', FILE_IGNORE_NEW_LINES);

$koukoh = file('http://xxxxx.jp/koukoh.txt', FILE_IGNORE_NEW_LINES);

$daigaku = file('http://xxxxx.jp/daigaku.txt', FILE_IGNORE_NEW_LINES);

$shakaijin = file('http://xxxxx.jp/shakaijin.txt', FILE_IGNORE_NEW_LINES);

foreach($data as $val){

$addval = '';

if (preg_match('/([高大][卒社])@.*?$/', $val, $mch)){

$addval = '→'.array_rand($koukoh);

if ($mch[1] == '大') $addval .= '→'.array_rand($daigaku);

if ($mch[2] == '社') $addval .= '→'.array_rand($shakaijin);

}

print $val.$addval."
\n";

}

?>

ご回答有難うございます。

先の出力結果ですが、エラーは出なくて

「@ランダムな高校名 →ランダムな大学名 →ランダムな会社名 →」が

1行だけ表示されている様な状況でした。

また。「""」は配列の内容を表示だと思っておりました。

勉強不足で申し訳ありません。

アドバイスいただいた記述を何とか理解し試してみましたが、

data.txtがそのまま表示され、foreach以下が反映されていませんでした。

data.txtの行末には「高卒、大卒、高社、大社」のいづれかがあるか、

もしくは、上記が何も該当しない行があります。

該当する行末にはforeach以下の記述を反映させたいのですが・・・

正しい気がするのですが、何が間違っているのでしょうか。

ちなみに「$addval = '';」の「''」にはどの様な意味があるのでしょうか?

何度もお手数お掛けいたしますが、

宜しくお願い申し上げます。

2010/03/15 01:08:30
id:tezcello No.2

tezcello回答回数459ベストアンサー獲得回数692010/03/15 14:16:37

ポイント23pt

一部間違えていた所がありましたね。ごめんなさい。

マニュアルを斜めに読んでいて、array_rand() がキーしか返さないのを見落としました。

array_rand($daigaku) を $daigaku[array_rand($daigaku)] のように変更してください。


> 行末に、高卒がある場合は「@→高校名→」...という文字列を追加。

$addval = '→'.$koukoh[array_rand($koukoh)]; を

$addval = '@→'.$koukoh[array_rand($koukoh)]; に変更


最後に → が必要でしたので、

if ($mch[2] == '社')... の次に $addval .= '→'; を追加


以上の結果、以下のようにテストしました。

/*
$data = file('http://xxxxx.jp/data.txt', FILE_IGNORE_NEW_LINES);
$koukoh = file('http://xxxxx.jp/koukoh.txt', FILE_IGNORE_NEW_LINES);
$daigaku = file('http://xxxxx.jp/daigaku.txt', FILE_IGNORE_NEW_LINES);
$shakaijin = file('http://xxxxx.jp/shakaijin.txt', FILE_IGNORE_NEW_LINES);
*/
// file() で読む代わりに直接記述
$data = array(
  '123 abcdef ほげ大卒ほげ高社@ほにゃらら',
  '98 asdf あいうえ高卒@いろは',
  '456 qwerty 大卒@',
  '2 1 大社@',
  '98765 ふがふが @'
);
$koukoh = array('A高校', 'B高校', 'C高校');
$daigaku = array('X大学', 'Y大学', 'Z大学');
$shakaijin = array('L会社', 'M商社', 'N工業');
// ここまで

foreach($data as $val){
  $addval = '';
  if (preg_match('/([高大])([卒社])@/u', $val, $mch)){
	$addval = '→'.$koukoh[array_rand($koukoh)];
	if ($mch[1] == '大') $addval .= '→'.$daigaku[array_rand($daigaku)];
	if ($mch[2] == '社') $addval .= '→'.$shakaijin[array_rand($shakaijin)];
  }
  print $val.$addval."<br>\n";
}

結果は、

123 abcdef ほげ大卒ほげ高社@ほにゃらら@→C高校→N工業→
98 asdf あいうえ高卒@いろは@→C高校→
456 qwerty 大卒@@→A高校→Y大学→
2 1 大社@@→C高校→X大学→M商社→
98765 ふがふが @

@@ と連続するのは、違和感がありますが、

> 「@→高校名→大学名→会社名→」という文字列を追加

とあるので仕様どおりかと。


> foreach以下が反映されていません

if (preg_match... 以下ですね。

preg_match() で指定した正規表現にマッチするものが無いためです。

UTF-8 で記述していないか、どこか間違っているかですね。@(英字) だと思っていましたが、@(日本語全角)でしょうか?適宜ご変更ください。(画面表示上はもの凄く見分けが付きにくいので...ご容赦ください)


> 「$addval = '';」の「''」にはどの様な意味があるのでしょうか?

$addval を空にセットしています。

foreach() でループしているので、前回の結果が残っています。それをリセットしている訳です。

「大卒」などの文字が無かった時に、何も表示しないようにする為です。


修正なので、コメント欄を開けておいて頂ければオープンするのに無駄なポイントは不要でしたのに。

id:himedaisan

ご丁寧に有難うございます。

UTF-8で保存しましたら、文字化けもなく表示できました。

もう2点ほどご教授いただければ非常に幸いです。

(1)それぞれのテキスト内容は何百行とあるのですが、

   fileで読み込む方法もありますでしょうか?

(2)最終的にdata.txtに付加した形で表示を行いたいのですが、

   data.txt内容のタブやスペースの状態を保持したまま、表示する方法はありますでしょうか?

度々のご質問で恐縮ですが、

宜しくお願い申し上げます。

ポイントの件、ご配慮いただき有難うございます。

どうにか解決したいので、問題ございません。

2010/03/16 06:36:30
id:tezcello No.3

tezcello回答回数459ベストアンサー獲得回数692010/03/16 11:24:27

ポイント22pt

> それぞれのテキスト内容は何百行とあるのですが、

> fileで読み込む方法もありますでしょうか?

「file() で読む代わりに直接記述」に対してのご質問でしょうか?

テスト環境では例示のアドレスでファイルを読み込む事が出来なかったからやったまでの事で、file() を使う事に何の問題もありません。

(メモリやCPUを贅沢に使えない環境で、読み込む内容が巨大だと、上手く行かない可能性もありますが)

data.txt は一度に全部を配列に読み込んで処理しなくても、1行ずつ読み込んでの処理も可能です。

fgets() についてお調べください。

http://jp.php.net/manual/ja/function.fgets.php


> data.txt内容のタブやスペースの状態を保持したまま、表示する方法はありますでしょうか?

<pre>
~~~
</pre>

のようにすれば、「~~~」内の空白要素もそのまま表示されると思います。

HTMLにどんなタグが存在するのかは、今一度ご確認を。

id:himedaisan

ご回答有難うございます。

>テスト環境では例示のアドレスでファイルを読み込む事が出来なかったからやったまでの事で、file() を使う事に何の問題もありません。

file() やfgets() でも試してみましたが、ファイルを読み込んでのマッチングがうまく出来ていないのか、foreach以下が反映されず、data.txtの内容だけの表示になってしまいます。

只、今回はお教えいただいた直接記述で対応しまして、取り急ぎ解決できました。

有難うございます!!!

今後も同様な処理(data.txt内容だけが変わる)がありますので、

file() での処理も引き続き、勉強していきたいと思います。

2010/03/17 00:47:05
id:tezcello No.4

tezcello回答回数459ベストアンサー獲得回数692010/03/18 16:38:17

ポイント22pt

スクリプト内に直接記述する方法と、file() で読み込む場合は、mbstring 関係の設定が関係するかもしれません。

http://www.php.net/manual/ja/mbstring.configuration.php#ini.mbst...

http://www.php.net/manual/ja/mbstring.configuration.php#ini.mbst...

http://www.php.net/manual/ja/mbstring.configuration.php#ini.mbst...

phpinfo() どんな値が設定されているか確認をされると良いかもしれません。

ご自身で php.ini が変更できる(または .htaccess を利用可能)なら、そちらの方で変更する手もありますが、スクリプトの最初でこんなのを書いておく手もあります。

mb_language('ja');
mb_internal_encoding('UTF-8');
ini_set('mbstring.http_input', 'pass');
ini_set('mbstring.http_output', 'pass');

蛇足でしょうけど、以下も追加しておくと、エラーの発見が早いかもしれません。

error_reporting(E_ALL);
ini_set('display_errors', '1');

回答したスクリプトは、『全て』UTF-8 で記述されている事を前提としています。

外部ファイル(***.txt)が UTF-8 であるかをご確認ください。

或いは、読み込んだ後、UTF-8 に変更するとか。


何れにしても、foreach() が機能しないのなら $data が配列になっていないです。

__この場合、data.txt の内容も表示されませんので、こちらは機能しているようです。

if (preg_match( )) が効いていない(=高校名などが出ない)なら、正規表現にマッチするものが無いと言う事です。( data.txt の書式が違うとかエンコードが違うとか...)

__エンコードを疑った為に mbstring関連の事が気になりました。

id:himedaisan

ご回答有難うございます。

外部ファイル(***.txt)が UTF-8になっていませんでした。

まだエラーが出るので、その他も恐らく基本的なことが出来ていないと思いますので、

もう一度、見直してからまたご質問させていただきます。

本当に有難うございました!

2010/03/20 18:22:33

コメントはまだありません

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

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

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

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