[英]Java: Parsing Strings with extra quotes
备用问题标题:分割制表符分隔列表内的逗号分隔列表。
我正在寻找不涉及标准Java例程以外的其他程序包的解决方案。 这必须是之前已经解决的问题,我只是不知道在Stackoverflow上使用哪个关键字来找到它!
我正在解析一个制表符分隔的文件。 分割行后,我在字段上执行错误检查,以防止不良数据进入程序。 除了一个领域,我几乎解决了所有问题。 输入线的基本布局是:
field1<tab>field2<tab>field3<tab>field4
根据设计,field3可以包含:
空字符串:
field1<tab>field2<tab><tab>field4
一串,带或不带空格:
field1<tab>field2<tab>Fred Flintstone<tab>field4
用逗号分隔的多个字符串:
field1<tab>field2<tab>Fred, Barney, Wilma<tab>field4
该行的读取和拆分如下:
String entry = pq2File.readline();
String[] temp;
temp = entry.split("\t", 4);
当我将输入行除以“ \\ t”时,在上述每种情况下,我的第三个字段(temp [2])的设置如下:
然后,我再次用“,”分割field3
ArrayList<String> names =
new ArrayList<String>(Arrays.asList(temp[2].split(",")));
在上述每种情况下,在ArrayList名称中给我以下值
当我使用文本编辑器创建文件或使用SQL语句将数据从我无法访问的外部远程系统中拉出时,所有这些操作都可以正确处理。 用户坚持使用MS EXCEL创建文件会带来问题。 在这种情况下,该行如下所示:
field1<tab>field2<tab>"Fred, Barney, Wilma"<tab>field4
当我解析行时,我的变量获取值
"Fred, Barney, Wilma"
并以“,”将其分割为:
“弗雷德
巴尼
威尔玛”
显然,我想摆脱多余的“”标记。我是否正在寻找解决方案,以便在拆分字段之前删除“”标记? 还是等到字段拆分之后才有意义(更少的代码),然后再看第一和最后一项。 我问,因为这行可能是:
field1<tab>field2<tab>"Fred Flintstone", "Barney Rubble", "Wilma Flintstone"<tab>field4
在这种情况下,我希望temp [2]变为:
"Fred Flintstone", "Barney Rubble", "Wilma Flintstone"
并且temp [2]的结果拆分应导致:
“弗雷德摩登原始人”
“巴尼·鲁伯”
“威尔玛打火石”
很好。
编辑已咨询设计团队,并确认对于所有字段,这些字段中都没有嵌入的选项卡。
此外,他们已经确认,在字段3中,该字段内没有带逗号的项目。
因此,输入如下内容:
field1<tab>field2<tab>"Fred Flintstone", "Barney, Wilma"<tab>field4
应为field3产生三个条目:
我正向他们施加压力,要求他们解决可能使整个问题困扰的另一个问题。
我想你想
不过,我想知道是否会有坏数据,例如
field1<tab>field2<tab>"Fred Flintstone", "Barney, Wilma"<tab>field4
导致各种脏数据。 您可能需要严格定义语法,而不是使用示例,此时解析应该变得很简单。
我建议您分两个级别对特定的解析器进行编码:
从理论上讲,我并没有在这里发表我的建议:
public class CombinedStringParser
{
private final String src;
private final char delimitter;
private int currentPos=0;
public CombinedStringParser(String src, char delimitter)
{
super();
this.src=src;
this.delimitter=delimitter;
}
public String nextToken()
{
int initialPos=this.currentPos;
int x=0;
while (this.currentPos < this.src.length())
{
char c=this.src.charAt(this.currentPos++);
if (c == this.delimitter)
{
x=-1;
break;
}
}
return this.src.substring(initialPos, this.currentPos + x);
}
public List<String> nextListOfTokens(char listDelimitter)
{
int initialPos=this.currentPos;
List<String> list=new ArrayList<String>();
while (this.currentPos < this.src.length())
{
char c=this.src.charAt(this.currentPos++);
if (c == this.delimitter)
{
break;
}
else
{
if (c == listDelimitter)
{
int p1=initialPos;
int p2=this.currentPos - 1;
if (this.src.charAt(p1) == '\"')
{
p1++;
}
if (this.src.charAt(p2 - 1) == '\"')
{
p2--;
}
list.add(this.src.substring(p1, p2));
initialPos=this.currentPos;
}
}
}
if (initialPos < this.currentPos)
{
int p1=initialPos;
int p2=this.src.length();
if (this.src.charAt(p1) == '\"')
{
p1++;
}
if (this.src.charAt(p2 - 1) == '\"')
{
p2--;
}
list.add(this.src.substring(p1, p2));
}
return list;
}
}
如何使用它:
CombinedStringParser parser=new CombinedStringParser(src, '\t');
String firstToken=parser.nextToken();
String secondToken=parser.nextToken();
List<String> thirdToken=parser.nextListOfTokens(',');
String fourthToken=parser.nextToken();
Appart从有效开始 ,由于其特殊性,该解决方案也是有效的 ,因为它只解析每个字符一次 。
只需先删除“,然后拆分。
temp = entry.replaceAll("\"", '').split("\t", 4);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.