Java 搜索大字符串以查看是否无效;参数";存在

Java 搜索大字符串以查看是否无效;参数";存在,java,string,Java,String,我有一根大绳子,类似于这根: BREW pot HTCPCP/1.0 接受添加:#牛奶;3#威士忌;飞溅 内容长度:5 内容类型:消息/咖啡壶 我还有一个阵列,其中添加了一些东西(威士忌、浓缩咖啡等)。如果这个大字符串包含的加法不在可用加法数组中,我需要做的是发送一个错误。例如,如果字符串的“接受添加”部分包含“#bricks;3”,则会产生错误,因为它不在数组中 我将如何在Java中实现这一点?我在实现这一部分时遇到了困难,尽管我已经编写了程序的其余部分(你们中的许多人可能会认识到)。我将如何

我有一根大绳子,类似于这根:

BREW pot HTCPCP/1.0

接受添加:#牛奶;3#威士忌;飞溅

内容长度:5

内容类型:消息/咖啡壶

我还有一个阵列,其中添加了一些东西(威士忌、浓缩咖啡等)。如果这个大字符串包含的加法不在可用加法数组中,我需要做的是发送一个错误。例如,如果字符串的“接受添加”部分包含“#bricks;3”,则会产生错误,因为它不在数组中


我将如何在Java中实现这一点?我在实现这一部分时遇到了困难,尽管我已经编写了程序的其余部分(你们中的许多人可能会认识到)。我将如何编写以下问题的代码,重点是加法不可用?

您将解析字符串。查看它,您可以为每行添加一组选项,这样就可以查找所有以ACCEPT-ADDITIONS开头的行。然后必须提取添加项,这些添加项似乎用分号分隔,表示String.split()。然后迭代结果数组以查找添加项


或者您可以创建语法,并使用ANTLR之类的工具来生成解析器。

这段代码对输入做了一些假设。看起来你可以将每个代币进一步拆分为#;组件。为可接受的liquids参数使用列表将稍微清理代码(只需使用liquids.contains(字符串s))

static String[]liquids={“#milk;3”,“#威士忌;splash”};
公共静态空解析字符串(字符串输入)
{
//把绳子一行一行地拆开。
String[]line=input.split(“+”\n');
对于(int line_index=0;line_index16)
{
//假设你用“#”来划分
String[]tokens=行[line_index]。拆分(“#”);
如果(tokens.length>1)
{
//从索引=1开始终止“接受添加:”
对于(int-token\u-index=1;token\u-index
下面是一个使用正则表达式的可能解决方案。它从有效负载中提取“Accept Additions”行,然后检查表单
#foo;条形码

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) {
            // ...
        }
    }
}
第一个regexp从请求中提取相关行。第二种方法提取键值对。请注意以下注意事项:

  • 此方法无法正确拾取格式错误的请求-仅接收无效的“密钥”

  • 如果允许不同的大写形式(例如“接受添加”、“接受添加”),请添加Pattern.CASE_不区分大小写标志,即
    Pattern.MULTILINE&Pattern.CASE_不区分大小写


测试它的一种快速方法是使用Arrays类来检查(而不是迭代):比如Arrays.binarySearch(additionsArray,parsedString),它将返回不确定二进制搜索在这里有何帮助。你基本上是在寻找一个集合中没有出现在另一个集合中的成员。因此,我将创建一个包含有效添加项的哈希集,并对文件中指定的值进行迭代。这非常接近我想要的值,尽管数组中不包含数量,因此数组中的值是沿着“#全脂牛奶”的线条。我猜OP想要一匙羹。。。与这种混乱的嵌套循环不同,我首先在StringReader中包装字符串,然后在LineNumberReader中包装字符串,然后使用readLine()循环。String.startsWith()是一种明确标识所关心的行的方法(尽管您应该首先修剪()),并且没有很好的理由检查行长度。将标记化重构为其自己的方法以实现潜在的可重用性,如我在下面所述,探测哈希集以查找有效/无效的值。我已经尝试了您的代码,但在尝试从客户端发送字符串时收到了IllegalStateException。异常消息是什么?我假设第一个regexp不匹配。我稍微放松了一下,并添加了一个“注意事项”列表。。。
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) {
            // ...
        }
    }
}