回答編集履歴

5

加筆修正

2021/01/28 02:41

投稿

退会済みユーザー
test CHANGED
@@ -139,3 +139,13 @@
139
139
 
140
140
 
141
141
  となりますが、このやり方は1箇所の決まったセルでのみ余計に分割されるときにしか対応できません。
142
+
143
+
144
+
145
+ ---
146
+
147
+
148
+
149
+ 余計な分割を防げるよう「"」で囲ってあるデータなら、
150
+
151
+ `$objFile->setCsvControl("\t");` の行だけ削除でいけます!

4

見直し

2021/01/28 02:41

投稿

退会済みユーザー
test CHANGED
@@ -76,7 +76,9 @@
76
76
 
77
77
  の様子から察するに、CSVというよりもTSVなのですね?
78
78
 
79
+ タブで区切られているときの分割にはいいですが、「,」で区切られているときは `$objFile->setCsvControl("\t");` が余計なコードになってます。
80
+
79
- でもタブでは区切られておらず、ファイル上では「,」で区切られているから分割できていないのです。
81
+ でもファイルではタブでは区切られておらず、「,」で区切られているから分割できていないのです。
80
82
 
81
83
 
82
84
 

3

加筆修正

2021/01/28 02:29

投稿

退会済みユーザー
test CHANGED
@@ -37,3 +37,103 @@
37
37
  foreachループの終わりに `$list[] = $row;` を置くことで、
38
38
 
39
39
  1行分のデータを逐一処理して全行分処理する繰り返し処理になります。
40
+
41
+
42
+
43
+ ---
44
+
45
+
46
+
47
+ > /* $row[0]に1行分のデータがカンマ区切りで格納されている状態です。
48
+
49
+ > * array(1) {
50
+
51
+ > * [0] => string(xxx) "1,000いろは|12000,aaa,....."
52
+
53
+ > * }
54
+
55
+ > */
56
+
57
+
58
+
59
+ という様子から察すると、CSVファイルとして想定するフォーマットになってないために、
60
+
61
+ 機械的な分割処理ができてない状況だろうと思います。
62
+
63
+
64
+
65
+ ```php
66
+
67
+ $objFile = new SplFileObject($meta['uri'], 'rb');
68
+
69
+ $objFile->setFlags(SplFileObject::READ_CSV | SplFileObject::READ_AHEAD | SplFileObject::SKIP_EMPTY);
70
+
71
+ $objFile->setCsvControl("\t");
72
+
73
+ ```
74
+
75
+
76
+
77
+ の様子から察するに、CSVというよりもTSVなのですね?
78
+
79
+ でもタブでは区切られておらず、ファイル上では「,」で区切られているから分割できていないのです。
80
+
81
+
82
+
83
+ じゃぁ`$objFile->setCsvControl("\t");`の行を削除すればいいかというと、
84
+
85
+ おそらく「,」を検出して機械的に分割してしまうため、
86
+
87
+ それも都合悪い話なのでしょう。
88
+
89
+
90
+
91
+ 「,」が1つ目にしか現れないという前提なら、
92
+
93
+ まず `$objFile->setCsvControl("\t");` の行を削除して、
94
+
95
+ こんなコードを足したらどうでしょう。
96
+
97
+
98
+
99
+ ```php
100
+
101
+ <?php
102
+
103
+
104
+
105
+ $csv_string = '1,000いろは|12000,aaa,bbb,ccc'; // 4つのセルがあると仮定する
106
+
107
+ $cells = explode(',', $csv_string);
108
+
109
+ if (count($cells) > 4) { // 4つより多いと検出→1つ目と2つ目を再結合させる
110
+
111
+ $cells[1] = $cells[0] . ',' . $cells[1];
112
+
113
+ array_shift($cells);
114
+
115
+ }
116
+
117
+ print_r($cells);
118
+
119
+ ```
120
+
121
+ 結果は
122
+
123
+ > Array
124
+
125
+ > (
126
+
127
+ > [0] => 1,000いろは|12000
128
+
129
+ > [1] => aaa
130
+
131
+ > [2] => bbb
132
+
133
+ > [3] => ccc
134
+
135
+ > )
136
+
137
+
138
+
139
+ となりますが、このやり方は1箇所の決まったセルでのみ余計に分割されるときにしか対応できません。

2

加筆修正

2021/01/28 02:27

投稿

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

1

加筆修正

2021/01/28 00:47

投稿

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