質問するログイン新規登録

回答編集履歴

5

加筆修正

2021/01/28 02:41

投稿

退会済みユーザー
answer CHANGED
@@ -68,4 +68,9 @@
68
68
  > [3] => ccc
69
69
  > )
70
70
 
71
- となりますが、このやり方は1箇所の決まったセルでのみ余計に分割されるときにしか対応できません。
71
+ となりますが、このやり方は1箇所の決まったセルでのみ余計に分割されるときにしか対応できません。
72
+
73
+ ---
74
+
75
+ 余計な分割を防げるよう「"」で囲ってあるデータなら、
76
+ `$objFile->setCsvControl("\t");` の行だけ削除でいけます!

4

見直し

2021/01/28 02:41

投稿

退会済みユーザー
answer CHANGED
@@ -37,7 +37,8 @@
37
37
  ```
38
38
 
39
39
  の様子から察するに、CSVというよりもTSVなのですね?
40
+ タブで区切られているときの分割にはいいですが、「,」で区切られているときは `$objFile->setCsvControl("\t");` が余計なコードになってます。
40
- でもタブでは区切られておらず、ファイル上では「,」で区切られているから分割できていないのです。
41
+ でもファイルではタブでは区切られておらず、「,」で区切られているから分割できていないのです。
41
42
 
42
43
  じゃぁ`$objFile->setCsvControl("\t");`の行を削除すればいいかというと、
43
44
  おそらく「,」を検出して機械的に分割してしまうため、

3

加筆修正

2021/01/28 02:29

投稿

退会済みユーザー
answer CHANGED
@@ -17,4 +17,54 @@
17
17
  `$list[] = $row;`
18
18
  とでもすれば配列`$list`の最後尾に追加されたりするわけで、
19
19
  foreachループの終わりに `$list[] = $row;` を置くことで、
20
- 1行分のデータを逐一処理して全行分処理する繰り返し処理になります。
20
+ 1行分のデータを逐一処理して全行分処理する繰り返し処理になります。
21
+
22
+ ---
23
+
24
+ > /* $row[0]に1行分のデータがカンマ区切りで格納されている状態です。
25
+ > * array(1) {
26
+ > * [0] => string(xxx) "1,000いろは|12000,aaa,....."
27
+ > * }
28
+ > */
29
+
30
+ という様子から察すると、CSVファイルとして想定するフォーマットになってないために、
31
+ 機械的な分割処理ができてない状況だろうと思います。
32
+
33
+ ```php
34
+ $objFile = new SplFileObject($meta['uri'], 'rb');
35
+ $objFile->setFlags(SplFileObject::READ_CSV | SplFileObject::READ_AHEAD | SplFileObject::SKIP_EMPTY);
36
+ $objFile->setCsvControl("\t");
37
+ ```
38
+
39
+ の様子から察するに、CSVというよりもTSVなのですね?
40
+ でもタブでは区切られておらず、ファイル上では「,」で区切られているから分割できていないのです。
41
+
42
+ じゃぁ`$objFile->setCsvControl("\t");`の行を削除すればいいかというと、
43
+ おそらく「,」を検出して機械的に分割してしまうため、
44
+ それも都合悪い話なのでしょう。
45
+
46
+ 「,」が1つ目にしか現れないという前提なら、
47
+ まず `$objFile->setCsvControl("\t");` の行を削除して、
48
+ こんなコードを足したらどうでしょう。
49
+
50
+ ```php
51
+ <?php
52
+
53
+ $csv_string = '1,000いろは|12000,aaa,bbb,ccc'; // 4つのセルがあると仮定する
54
+ $cells = explode(',', $csv_string);
55
+ if (count($cells) > 4) { // 4つより多いと検出→1つ目と2つ目を再結合させる
56
+ $cells[1] = $cells[0] . ',' . $cells[1];
57
+ array_shift($cells);
58
+ }
59
+ print_r($cells);
60
+ ```
61
+ 結果は
62
+ > Array
63
+ > (
64
+ > [0] => 1,000いろは|12000
65
+ > [1] => aaa
66
+ > [2] => bbb
67
+ > [3] => ccc
68
+ > )
69
+
70
+ となりますが、このやり方は1箇所の決まったセルでのみ余計に分割されるときにしか対応できません。

2

加筆修正

2021/01/28 02:27

投稿

退会済みユーザー
answer CHANGED
@@ -1,9 +1,20 @@
1
+ `$objFile`にファイルから読み込んだ全行のデータが入っていて、
2
+ それをforeachループよって1行分ずつ$rowで処理するっていう流れになているのは理解できますか?
3
+
4
+ 1つの行データ`$row`の
5
+ 1つ目のデータが`$row[0]`に
6
+ 2つ目のデータが`$row[1]`にと分割されて納められているのだから、
1
7
  [PHP: str_replace - Manual](https://www.php.net/manual/ja/function.str-replace.php)
2
8
  を使って、
3
- `$row[0] = str_replace(',', '', $row[0]);`してみたり
9
+ `$row[0] = str_replace(',', '', $row[0]);` などとすれば「,」を探して「」にする
4
- るい
10
+ つまりカンマ文字を削除すう意味になります。
5
- [PHP: preg_replace - Manual](https://www.php.net/manual/ja/function.preg-replace.php)を使って置き換えてもいいけどPCREエンジンを呼ぶほど高度なことをするわけじゃないだろうし。
6
11
 
12
+ 文字列の置換処理については類似のものとして
13
+ [PHP: preg_replace - Manual](https://www.php.net/manual/ja/function.preg-replace.php)もありますが、
14
+ 正規表現による高度で複雑な処理向けのものなので、今はstr_replace()が無難です。
15
+
7
16
  置き換え処理後に
8
17
  `$list[] = $row;`
9
- とでもすれば配列`$list`の最後尾に追加されたりするかもね。
18
+ とでもすれば配列`$list`の最後尾に追加されたりするわけで、
19
+ foreachループの終わりに `$list[] = $row;` を置くことで、
20
+ 1行分のデータを逐一処理して全行分処理する繰り返し処理になります。

1

加筆修正

2021/01/28 00:47

投稿

退会済みユーザー
answer CHANGED
@@ -1,5 +1,9 @@
1
1
  [PHP: str_replace - Manual](https://www.php.net/manual/ja/function.str-replace.php)
2
2
  を使って、
3
- `$row[0] = str_replace(',', '', $row[0])`してみたり、
3
+ `$row[0] = str_replace(',', '', $row[0]);`してみたり、
4
4
  あるいは
5
- [PHP: preg_replace - Manual](https://www.php.net/manual/ja/function.preg-replace.php)を使って置き換えてもいいけどPCREエンジンを呼ぶほど高度なことをするわけじゃないだろうし。
5
+ [PHP: preg_replace - Manual](https://www.php.net/manual/ja/function.preg-replace.php)を使って置き換えてもいいけどPCREエンジンを呼ぶほど高度なことをするわけじゃないだろうし。
6
+
7
+ 置き換え処理後に
8
+ `$list[] = $row;`
9
+ とでもすれば配列`$list`の最後尾に追加されたりするかもね。