我需要为从文件中读取的字符串编写一个正则表达式
apple,boy,cat,"dog,cat","time\" after\"noon"
我需要把它分成
苹果 男生 猫 狗猫 中午之后的时间
我尝试使用
Pattern pattern =
Pattern.compile("[\\\"]");
String items[]=pattern.split(match);
第二部分,但我无法得到正确的答案,你能帮我吗?
我需要为从文件中读取的字符串编写一个正则表达式
apple,boy,cat,"dog,cat","time\" after\"noon"
我需要把它分成
苹果 男生 猫 狗猫 中午之后的时间
我尝试使用
Pattern pattern =
Pattern.compile("[\\\"]");
String items[]=pattern.split(match);
第二部分,但我无法得到正确的答案,你能帮我吗?
由于您的问题更多的是解析问题而不是正则表达式问题,因此这是另一种可行的解决方案:
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:已修复。应该像现在宣传的那样工作。还对其进行了修改以测试行号和列号的跟踪。
第一件事: String.split() 使用正则表达式来查找分隔符,而不是子字符串。
编辑:我不确定这是否可以用 String.split() 来完成。我认为在只匹配逗号的同时处理引号的唯一方法是预读和后视,这在很多情况下都会中断。
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());
}
但是,是的,我会回应上面的那个人并说如果不需要使用正则表达式,那么手动执行它可能更简单。
但后来我想我快到了。它吐出来了……哦,嘿,我明白这里发生了什么。我想我可以解决这个问题。
但是我要回应上面的那个人,并说如果不需要使用正则表达式,最好一次使用一个字符并手动实现逻辑。如果您的正则表达式不完美,那么它可能会导致各种不可预知的怪异现象。
我不太确定,但你可以试试Pattern.compile("[\\\\"]");
\
是一个转义字符,可以使用来检测\
表达式中的a。\\\\
在另一种情况下,类似的事情对我有用,我希望它也能解决你的问题。