我需要为从文件中读取的字符串写一个正则表达式
apple,boy,cat,"dog,cat","time\" after\"noon"
我需要将其拆分为
apple boy cat dog,cat time"after"noon
我尝试使用
Pattern pattern =
Pattern.compile("[\\\"]");
String items[]=pattern.split(match);
对于第二部分,但我无法得到正确答案,你能帮我解决这个问题吗?
答案 0 :(得分:3)
由于您的问题更多的是解析问题而不是正则表达式问题,因此这是另一个可行的解决方案:
public class CsvReader {
Reader r;
int row, col;
boolean endOfRow;
public CsvReader(Reader r){
this.r = r instanceof BufferedReader ? r : new BufferedReader(r);
this.row = -1;
this.col = 0;
this.endOfRow = true;
}
/**
* Returns the next string in the input stream, or null when no input is left
* @return
* @throws IOException
*/
public String next() throws IOException {
int i = r.read();
if(i == -1)
return null;
if(this.endOfRow){
this.row++;
this.col = 0;
this.endOfRow = false;
} else {
this.col++;
}
StringBuilder b = new StringBuilder();
outerLoop:
while(true){
char c = (char) i;
if(i == -1)
break;
if(c == ','){
break;
} else if(c == '\n'){
endOfRow = true;
break;
} else if(c == '\\'){
i = r.read();
if(i == -1){
break;
} else {
b.append((char)i);
}
} else if(c == '"'){
while(true){
i = r.read();
if(i == -1){
break outerLoop;
}
c = (char)i;
if(c == '\\'){
i = r.read();
if(i == -1){
break outerLoop;
} else {
b.append((char)i);
}
} else if(c == '"'){
r.mark(2);
i = r.read();
if(i == '"'){
b.append('"');
} else {
r.reset();
break;
}
} else {
b.append(c);
}
}
} else {
b.append(c);
}
i = r.read();
}
return b.toString().trim();
}
public int getColNum(){
return col;
}
public int getRowNum(){
return row;
}
public static void main(String[] args){
try {
String input = "apple,boy,cat,\"dog,cat\",\"time\\\" after\\\"noon\"\nquick\"fix\" hello, \"\"\"who's there?\"";
System.out.println(input);
Reader r = new StringReader(input);
CsvReader csv = new CsvReader(r);
String s;
while((s = csv.next()) != null){
System.out.println("R" + csv.getRowNum() + "C" + csv.getColNum() + ": " + s);
}
} catch(IOException e){
e.printStackTrace();
}
}
}
运行此代码,我得到输出:
R0C0: apple
R0C1: boy
R0C2: cat
R0C3: dog,cat
R0C4: time" after"noon
R1C0: quickfix hello
R1C1: "who's there?
这应该很适合你的需求。
但有一些免责声明:
编辑:查看csv格式,发现没有真正的标准,但更新了我的代码以捕获通过加倍而不是反斜杠转义的引号。
编辑2:已修复。应该像现在广告一样工作。还修改了它以测试行号和列号的跟踪。
答案 1 :(得分:0)
首先:String.split()使用正则表达式来查找分隔符,而不是子字符串。
编辑:我不确定是否可以使用String.split()完成此操作。我认为只有匹配逗号才能处理引号的唯一方法是通过readahead和lookbehind,并且在很多情况下都会破坏。
Edit2:我很确定它可以用正则表达式完成。我确信这一个案例可以通过string.split()来解决 - 但一般解决方案并不简单。
基本上,你正在寻找任何不是逗号作为输入[^,]的东西,你可以将引号作为单独的字符处理。我自己已经完成了大部分工作。我得到这个作为输出:
apple
boy
cat
dog
cat
time\" after\"noon
但我不确定为什么会有这么多空白。
我的完整代码是:
String input = "apple,boy,cat,\"dog,cat\",\"time\\\" after\\\"noon\"";
Pattern pattern =
Pattern.compile("(\\s|[^,\"\\\\]|(\\\\.)||(\".*\"))*");
Matcher m = pattern.matcher(input);
while(m.find()){
System.out.println(m.group());
}
但是,是的,我会回应上面的那个人并说如果没有要求使用正则表达式,那么手动执行它可能更简单。
但是我想我差不多了。它吐出来......哦,嘿,我看到这里发生了什么。我想我可以解决这个问题。
但是我要回应上面的那个人并说如果不需要使用正则表达式,那么最好一次做一个字符并手动实现逻辑。如果你的正则表达式不完美,那么它可能会造成各种不可预测的怪异。
答案 2 :(得分:0)
我对此并不十分确定,但你可以去 Pattern.compile("[\\\\"]");
\
是一个转义字符,要检测表达式中的\
,可以使用\\\\
。
类似的事情在another context中对我有用,我希望它也能解决你的问题。