【问题标题】:Get Substring of A String with Spaces and Quotes using IndexOf使用 IndexOf 获取带有空格和引号的字符串的子字符串
【发布时间】:2018-01-11 03:23:18
【问题描述】:

我有以下字符串并想提取规则的内容,即我的规则描述如下所示:

rule "My Rule Description Looks Like This"      
        followed by some white space other characters such as quotes".

当我使用以下内容时,我得到一个 java.lang.StringIndexOutOfBoundsException: String index out of range: -2:

String ruleName = rule.substring(rule.indexOf("rule \"" + 7, rule.indexOf("\""));

当我使用 lastIndexOf:

String ruleName = rule.substring(rule.indexOf("rule \"" + 7, rule.lastIndexOf("\""));

代码执行正常,但输出如下:

My Rule Description Looks Like This"        
        followed by some white space other characters and quotes

任何想法为什么第一个选项使用 indexOf 引发异常?

【问题讨论】:

  • 你调用的东西看起来像substring(11, 4)
  • 您的子字符串调用无法编译。
  • 很惊讶没有人提到"rule \"" + 7 是字符串"rule "7"
  • @MichaelMarkidis 数一下括号,它少了一个。这只是一个错字。

标签: java indexof lastindexof


【解决方案1】:

对于任何类型的复杂文本提取,您可能需要考虑使用正则表达式。这是一个可以提取规则的简短脚本,它避免了令人讨厌的字符串操作,正如您所见,这很容易出错。

String line = "rule \"My Rule Description Looks Like This\"\n";
line += "followed by some white space other characters such as quotes\".";
String pattern = "rule\\s+\"(.*?)\".*";

Pattern r = Pattern.compile(pattern, Pattern.DOTALL);
Matcher m = r.matcher(line);
if (m.find()) {
   System.out.println("Found a rule: " + m.group(1) );
} else {
   System.out.println("Could not find a rule.");
}

输出:

My Rule Description Looks Like This

演示在这里:

Rextester

【讨论】:

  • 感谢您的解释,我会考虑改用模式。
  • 如果您想了解String#substring() 的错误之处,请查看其他答案,但如果您的要求比这更复杂,那么正则表达式可能是您更好的时间投资。跨度>
【解决方案2】:

indexOf 返回指定字符串的第一次出现的索引。

因此,您的第一个示例将尝试从索引 7 开始子字符串(0 是找到您的字符串的索引,然后添加 7),并以索引 5 结束(找到第一个 " 的位置)。

substring(int beginIndex, int endIndex) 方法中有一些逻辑,如果从结束索引中减去开始索引 StringIndexOutOfBoundsException,其值为:

int subLen = endIndex - beginIndex;
if (subLen < 0) {
    throw new StringIndexOutOfBoundsException(subLen);
}

您的第二个示例不会引发异常,但因为您使用的是lastIndexOf(),它将从 7 到字符串的末尾(其中有一个“)。

最好的解决方案是使用@Tim Biegeleisen 的回答中所示的正则表达式模式

【讨论】:

    【解决方案3】:

    来自the documentation

    公共字符串子字符串(int beginIndex,int endIndex)

    如果beginIndex为负数,或者endIndex大于这个String对象的长度,或者beginIndex大于endIndex。

    您正在呼叫rule.substring(rule.indexOf("rule \"" + 7, rule.indexOf("\""))。第一个参数给你第一个rule + quote的索引,比如说x,+ 7。第二个参数给你第一个引号的索引,即x + 6x - 中的字符数rule 。所以你调用的是substring (x + 7, x +6),属于异常情况:

    第一个参数大于第二个。

    在你的第二种情况下,使用lastIndexOf,你得到第二个报价,所以你没有这个问题。

    【讨论】:

    • 这是不正确的。 indexOf 的第一个参数是一个字符串;因此,"rule \"" + 7 实际上是字符串 "rule "7"
    • @MichaelMarkidis 因为他得到了一个异常而不是一个错误,你可以假设他写了String ruleName = rule.substring(rule.indexOf("rule \"") + 7, rule.indexOf("\""));
    猜你喜欢
    • 1970-01-01
    • 2016-06-09
    • 2010-09-09
    • 2023-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多