2013-05-10 77 views
1

我的java應用程序具有一個小命令行。爲了解析參數,首先讀入行,然後使用string.split("\\s+")切成一個數組。參數的格式爲名稱:值,通常既不是名稱應該有空格。在文件路徑之外的空格上拆分字符串

介紹一個新功能,當應該是一個文件路徑時,我遇到了一個問題。如果路徑包含空格(轉義或不轉義),斬波算法當然會分割路徑。

問:什麼正則表達式將允許我將字符串拆分爲參數數組而沒有拆分(轉義)文件路徑。


我認爲轉義路徑的形式爲 /folder/part1\ part2.txt,但是合理的替代語法也是有效的。

如果更容易string.split(" ")也是可以接受的。

回答

0

對於語法:/folder/part1\ part2.txt

正則表達式來解決這個問題需要一個負向後看,檢查是否之前的字符我們正在尋找的模式不是\。正則表達式將是(?<!\\)\s+(?<!\\)是後面的部分,\\是我們不想看到的模式。 \s+是我們正在尋找的模式 - 某種空間。要在java中使用這個正則表達式,你必須正確地轉義它,如:string.split("(?<!\\\\)\\s+")

這適用於UNIX樣式的文件路徑,例如,如果您想將文件傳遞到​​,則可能必須刪除反斜槓。


有關語法 "/folder/part1 part2.txt"

這可能是一個比較普遍的做法,但是引入了額外的工作。這個想法是循環遍歷字符串,每次我們看到一個空間時,我們都會將前一部分保存到一個列表中,除非空格在轉義部分。例如:

List<String> parts = new ArrayList<String>(); 
boolean escaped = false; 
StringBuilder stringBuilder = new StringBuilder(); 
for(int i = 0; i < string.length(); i++) { 
    char c = string.charAt(i); 
    if(!escaped && (c == ' ' || c == '\t')) { // Space in non-escaped part 
     parts.add(stringBuilder.toString());  // Put buffer in list 
     stringBuilder = new StringBuilder(); 
    } else if (c == '"')  // Escape sign 
     escaped = !escaped; // Toggle escape status 
    else 
     stringBuilder.append(c); // Add char to buffer 
} 
parts.add(stringBuilder.toString()); // Put the last buffer into the array 

如果必要的列表可以被轉換爲使用

String[] args = parts.toArray(new String[parts.size()]) 

此格式允許UNIX和Windows風格的路徑的陣列。生成的數組將包含文件路徑而不包含的引號。

1

最好的代碼是不寫代碼。所以,不要自己解析命令行。使用流行的圖書館之一。例如歷久彌新jackarta cli project還是現代的,基於註解庫args4j

+0

感謝您的鏈接,我以前沒有聽說過args4j庫,這似乎是一個有趣的方法。無論我是否會走到圖書館,都會很有趣,知道是否有針對特定問題的解決方案。 – Samuel 2013-05-10 13:42:47