备用问题标题:拆分以制表符分隔的列表中的逗号分隔列表。
我正在寻找一种不涉及其他包装的解决方案 比标准的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);
当我将输入行拆分为&#34; \ t&#34;在上述每种情况下,我的第三个字段(temp [2])设置如下:
然后我再次通过&#34;,&#34;分割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"
将其拆分为&#34;,&#34;结果:
&#34;佛瑞德
巴尼
威尔玛&#34;
显然我想摆脱额外的&#34;分数。我在寻找解决方案来消除&#34;我分裂之前的标记?或者更有意义(更少的代码)等待字段分割后,然后只看第一个和最后一个项目。我问,因为这条线可能是:
field1<tab>field2<tab>"Fred Flintstone", "Barney Rubble", "Wilma Flintstone"<tab>field4
在这种情况下,我希望temp [2]成为:
"Fred Flintstone", "Barney Rubble", "Wilma Flintstone"
并导致temp [2]的分割应该导致:
&#34; Fred Flintstone&#34;
&#34; Barney Rubble&#34;
&#34; Wilma Flintstone&#34;
这没关系。
修改 已咨询设计团队并确认对于所有字段,字段中不能嵌入选项卡。
此外,他们已经确认在字段3中,字段内没有嵌入逗号。
因此,输入如:
field1<tab>field2<tab>"Fred Flintstone", "Barney, Wilma"<tab>field4
应该为field3产生三个条目:
我正在向他们提出另一个可能使整个问题无法解决的问题......
答案 0 :(得分:1)
我想你想要
不过,我想知道是否有不良数据,比如
field1<tab>field2<tab>"Fred Flintstone", "Barney, Wilma"<tab>field4
导致各种脏数据。您可能需要严格定义语法而不是使用示例,此时解析应该变得微不足道。
答案 1 :(得分:1)
我建议您在两个级别编写特定解析器:
不要理论上听起来如此,我在这里发布我的建议:
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();
来自有效的公寓,由于其特殊性,此解决方案也高效,因为它只解析每个 。
答案 2 :(得分:0)
只需删除&#34;首先,然后拆分。
temp = entry.replaceAll("\"", '').split("\t", 4);