最近遇到一个问题,具体需求如下:
有一个字符串,可能会有中文/英文/数字/逗号/引号等字符,现在需要按照逗号分割输出,如果有一个待输出的字符串里面包含了引号的话,需要将其里面的值完整输出,并且如果里面带有连续两个双引号的话需要将其改为单个引号输出,整个程序编写过程不能使用split和replace相关的api。
举个例子吧:
我,19,"2,""你we"",""3333"",king,""","9,0,""you"",queue
需要输出成:
我 19 2,"你we","3333",king," 9,0,"you",queue
也就是说引号内的字符串要忽略掉逗号分割,同时如果里面有两个引号的话要在输出的时候转换成一个引号。
这个的难度就在于区别出一对引号内部的值,同时又不能用split方法,所以我就想到了用字符串遍历的方法。逻辑分两段,第一段是构建单引号分割字符段,通过扫描,如果发现有单引号,就判断下一个是不还是单引号,如果是的话直接加到新字符串中并下标直接加1(在构建新字符串的时候把下一个引号给忽略掉),如果不是的话,用竖线代替这个双引号,如上例子,新字符串将变成:我,19,|2,"你we","3333",king,"|,|9,0,"you",queue;第二段逻辑是遍历新字符串,构造需要输出的字符串,如果遇到逗号,就将之前的输出,否则将字符加入到字符串中,如果遇到竖线,就给个标记,然后根据标记去加入新字符串直至出现下一个竖线,然后再将标记置回初始值。
献上我的代码,抛砖引玉,望大神们拍砖。
package com.wzm.test;
public class CustomSplitExample {
public static void main(String[] args) {
String waiting4split = "我,19,\"2,\"\"你we\"\",\"\"3333\"\",king,\"\"\",9,queue";
char[] strChars = waiting4split.toCharArray();
int pattern1Int = "\"".toCharArray()[0];
StringBuffer sbBuffer = new StringBuffer();
int i = 0;
while(i<strChars.length){
int c = (int)strChars[i];
if(c == pattern1Int&&i!=strChars.length-1){
if((int)strChars[i+1]==pattern1Int){
sbBuffer.append(strChars[i]);
i++;
}else{
sbBuffer.append("|");
}
}else{
sbBuffer.append(strChars[i]);
}
i++;
}
System.out.print(sbBuffer);
i = 0;
char[] strChar1 = sbBuffer.toString().toCharArray();
int pattern1 = ",".toCharArray()[0];
int pattern2 = "|".toCharArray()[0];
System.out.println("");
System.out.println("输出结果为:");
StringBuffer res = new StringBuffer();
int flag = 0;
while(i<strChar1.length){
int c = (int)strChar1[i];
if(pattern1==c&&flag==0){
if(!"".equals(res.toString().trim())){
System.out.print(res+" ");
}
res = new StringBuffer();
}else if(pattern2==c){
if(flag == 0){
flag = 1;
res = new StringBuffer();
}else if(flag == 1){
flag = 0;
if(!"".equals(res)){
System.out.print(res+" ");}
res = new StringBuffer();
}
}else {
res.append(strChar1[i]);
}
i++;
}
System.out.print(res);
}
}