[英]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.