Re: [問題] 分割字串的問題, 求救 >"<
可以先分割成兩件事
1.讀取行
2.解析行
3.你得到
行的條件
1.\n
2.跳脫字元 : [",',,]
我這裡只做到讀取行 而且沒有重構喔 只是提供參考而已
而且因為偷懶所以只讀單一字元
其實這裡有點效能考量
一次讀一個很浪費
可是讀多個要設計一下
一次全部讀出來也是很浪費
只是我這裡偷懶只讀一個比較方便
可以讀取每一行出來
接著就是要處理行
其實也是差不多的東西
就是針對行去處理
1.分割字元 : [,\t,,,]
2.跳脫字元 : [",',,,]
然後你就得到啦
其實原則差不多
可以試看看怎麼實作比較好
此外如果要讀取的檔案很大
就不要先讀完再處理
而是每讀一行就處理->callback方式
這樣效能會比較好
不然光是讀取內容就會爆漿拉
import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Test1 {
static class DoCsv{
public void docsv(List<String> row){
System.out.println("row="+row);
}
}
static void test2(String str,DoCsv docsv){
List<String> row = new ArrayList<String>();
char [] split = new char[]{',','\t'};
char [] escape = new char[]{'\"','\''};
StringBuilder col = new StringBuilder();
int _escape_ = 0 ;
for(char c : str.toCharArray()){
//escape
if( Arrays.binarySearch(escape, c) > -1 ){
//init=0 first_escape_=1 second_escape_=2
if(_escape_ == 1 ){
_escape_ = 2;
}
if(_escape_ == 0 ){
_escape_ = 1;
}
}
// \n end line
if( Arrays.binarySearch(split, c) > -1
&& ( _escape_ == 0 || _escape_ == 2 )
){
_escape_ = 0;
row.add(col.toString());
col.delete(0, col.length()) ;
continue;
}
//read
col.append(c);
}
row.add(col.toString());
docsv.docsv(row);
}
static void test1() throws IOException{
StringBuffer sb = new StringBuffer();
sb.append("a,,,bb,\n");
sb.append("a,,,bb,\n");
sb.append("a,,\"sadfsdaf \n sdf322121\",bb,\n");
sb.append("a,,,bb,\n");
sb.append("a,\"sadfsdaf sdf322121\",,bb,\n");
sb.append("a,,\'sadf sdf\',bb\n");
sb.append("a,中文,\'sadf sdf\',bb,\n");
sb.append("a,, ,bb,");
System.out.println(sb);
DoCsv docsv = new DoCsv();
char [] escape = new char[]{'\"','\''};
char linesp = '\n';
BufferedReader br
= new BufferedReader(new StringReader(sb.toString()));
System.out.println("***");
StringBuilder sbline = new StringBuilder();
int _escape_ = 0 ;
char c ;
for(int rc = br.read() ; rc > -1 ; rc = br.read()){
//System.out.println((char)rc);
c = (char)rc ;
//escape
if( Arrays.binarySearch(escape, c) > -1 ){
//init=0 first_escape_=1 second_escape_=2
if(_escape_ == 1 ){
_escape_ = 2;
}
if(_escape_ == 0 ){
_escape_ = 1;
}
}
// \n end line
if( c == linesp
&& ( _escape_ == 0 || _escape_ == 2 )
){
_escape_ = 0;
//System.out.println("sbline="+sbline);
test2(sbline.toString(),docsv);
sbline.delete(0, sbline.length()) ;
continue;
}
//read
sbline.append(c);
}
//System.out.println("sbline="+sbline);
test2(sbline.toString(),docsv);
br.close();
}
public static void main(String [] args){
try {
test1();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
恩我還是試看看好了
看起來結果還滿符合預期的
只是要重構喔
我只是用腳本的方式寫的喔
然後你就會發現還是用現成的套件比較簡單
XD
PS.我只是要賺P幣而已 XD
※ 引述《bera (k.k)》之銘言:
: 以下是目前我測試的程式碼, 但不是我要的結果 >"<
: public static void main(String[] args) {
: String str = "小尚,\"Abby, Sun\",girl,0911-XXX0L9,si,1988/11/20";
: String[] cells = str.split(",");
: System.out.println(str);
: for(int i = 0 ; i < cells.length ; i++){
: System.out.println("cells["+i+"]:"+cells[i]);
: }
: }
: Console output:
: 小尚,"Abby, Sun",girl,0911-XXX0L9,si,1988/11/20
: cells[0]:小尚
: cells[1]:"Abby
: cells[2]: Sun"
: cells[3]:girl
: cells[4]:0911-XXX0L9
: cells[5]:si
: cells[6]:1988/11/20
: 我想要的結果是
: cells[0]:小尚
: cells[1]:"Abby, Sun"
: cells[2]:girl
: cells[3]:0911-XXX0L9
: cells[4]:si
: cells[5]:1988/11/20
: 說明:
: 資料都是用逗號來當分隔符號
: 但是如果資料裡有逗號想呈現
: 就會用雙引號括住
: 後來想用indexOf來做
: 但做到
: String str = "小尚,\"Abby, Sun\",girl,0911-XXX0L9,si,1988/11/20";
: int idxStart;
: int idxEnd;
: String strTemp;
: if(str.indexOf("\"")>-1){
: idxStart = str.indexOf("\"");
: System.out.println(str.indexOf("\""));
: idxEnd = str.indexOf("\"", idxStart+1);
: strTemp = str.substring(idxStart+1, idxEnd);
: System.out.println(strTemp);
: }
: 就沒想法了
: 而進階的資料可能會像
: String str =
: "小尚,\"Abby, Sun\",girl,0911-XXX0L9,\"si, Tokyo, Relax~~\",1988/11/20";
: 這樣的形式
: 不知道可不可以請教一下思路呢? 謝謝~~~
--
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 163.29.28.131
※ 編輯: swpoker 來自: 163.29.28.131 (05/03 09:59)
※ 編輯: swpoker 來自: 163.29.28.131 (05/03 10:19)
→
05/03 10:40, , 1F
05/03 10:40, 1F
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 4 之 6 篇):