2009-05-05 51 views
1

我有一個大的字符串,與此類似:搜索大的字符串是否無效 「參數」 的存在

BREW鍋HTCPCP/1.0

的Accept-加法:#milk; 3#威士忌;濺

內容長度:5

內容類型:信息/咖啡壺

我也有一個數組添加(#whiskey,#espresso等)。我需要做的是發送一個錯誤,如果這個大字符串包含一個不在可用添加數組中的添加。例如,如果字符串的「Accept-Additions」部分包含「#bricks; 3」,則會產生一個錯誤,因爲它不在數組中。

我會怎樣在Java中去解決這個問題?儘管我已經編寫了程序的其餘部分(您可能會認識到這一點),但我在執行此部分時遇到了困難。我將如何編碼以下問題,重點不在於可用的添加?

回答

1

該代碼對輸入做了一些假設。它看起來好像你可以將每個標記進一步劃分爲#;組件。用列表您可以接受的液體參數將清理代碼位(只使用liquids.contains(String s)將)

static String[] liquids = {"#milk;3", "#whiskey;splash"}; 

    public static void parseString(String input) 
    { 
    // Break the String down into line-by-line. 
    String[] lines = input.split("" + '\n'); 
    for (int line_index = 0; line_index < lines.length; line_index++) 
    { 
     if (lines[line_index].length() > 16) 
     { 
     // Assume you're delimiting by '#' 
     String[] tokens = lines[line_index].split("#"); 
     if (tokens.length > 1) 
     { 
      // Start at index = 1 to kill "Accept-Additions:" 
      for (int token_index = 1; token_index < tokens.length; token_index++) 
      { 
      boolean valid = false; 
      for (int liquids_index = 0; liquids_index < liquids.length; liquids_index++) 
      { 
       if (liquids[liquids_index].equals("#" + tokens[token_index])) 
       { 
       valid = true; 
       // break to save some time if liquids is very long 
       break; 
       } 
      } 
      if (!valid) 
      { 
       throwError("#" + tokens[token_index]); 
      } 
      } 
     } 
     } 
    } 
    } 

    public static void throwError(String error) 
    { 
    System.out.println(error + " is not in the Array!"); 
    } 
+0

這與我想要的非常接近,但數組不包含數量,所以數組中的值沿着「#全牛奶」的行。 – 2009-05-06 00:56:01

1

你會解析字符串。看着它,你每行有一組選項,所以你可以查找所有以ACCEPT-ADDITIONS開頭的行。然後,您必須提取添加,這些添加似乎與分號分開,表示String.split()。然後遍歷調用數組以找到添加項。

或者你可以創建一個語法,並使用諸如ANTLR之類的工具來生成解析器。

+0

和快速的方法來測試它是使用Arrays類檢查(而不是迭代):像Arrays.binarySearch(additionsArray,parsedString),這將返回<0,如果另外是不是你的陣列英寸 – mattandrews 2009-05-06 00:34:30

+0

不確定二進制搜索如何幫助您。你基本上是在尋找一個不出現在另一箇中的成員。所以我會創建一個帶有有效附加的HashSet,並迭代文件中指定的值。 – kdgregory 2009-05-06 12:53:04

0

下面是使用正則表達式一個可能的解決方案。它從有效載荷中提取'Accept-Additions'行,然後檢查形式爲#foo;bar的每個鍵值對。

final String[] VALID_ADDITIONS = { 
    "milk", "whiskey" 
}; 

final Pattern LINE = Pattern.compile("Accept-Additions:(.+)$", Pattern.MULTILINE); 
final Pattern ADDITIONS = Pattern.compile("#(.+?);([^#]+)"); 

void checkValidAdditions(String request) { 
    Matcher lineMatcher = LINE.matcher(request); 
    if (!lineMatcher.find()) { 
     // no additions - do whatever is appropriate here 
     throw new IllegalArgumentException("Additions line not found"); 
    } 
    String line = lineMatcher.group(1); 
    Matcher additions = ADDITIONS.matcher(line); 
    while (additions.find()) { 
     String key = additions.group(1); 
     //String value = additions.group(2); 

     boolean validKey = false; 
     for (String validAddition : VALID_ADDITIONS) { 
      if (key.equals(validAddition)) { 
       validKey = true; 
      } 
     } 
     if (!validKey) { 
      // ... 
     } 
    } 
} 

第一個正則表達式從請求中提取相關行。第二個提取鍵值對。請注意以下注意事項:

  • 此方法不會正確拾取格式錯誤的請求 - 只有無效的「密鑰」。

  • 如果您允許不同的大小寫(例如'ACCEPT-ADDITIONS','accept-additions'),請添加Pattern.CASE_INSENSITIVE標誌,即Pattern.MULTILINE & Pattern.CASE_INSENSITIVE