0

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

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 引发异常?

4

3 回答 3

2

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

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

演示在这里:

复试机

于 2017-08-03T13:33:46.323 回答
0

文档中

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

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

你在打电话rule.substring(rule.indexOf("rule \"" + 7, rule.indexOf("\""))。第一个参数为您提供第一个的索引,rule + quote例如x+ 7。第二个参数为您提供第一个引号的索引,即x + 6( x- 中的字符数rule 。所以您正在调用substring (x + 7, x +6),属于异常情况:

第一个参数大于第二个。

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

于 2017-08-03T13:34:26.093 回答
0

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

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

substring(int beginIndex, int endIndex)方法有一些逻辑,如果从结束索引中减去的开始索引 < 0,它将抛出 aStringIndexOutOfBoundsException值:

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

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

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

于 2017-08-03T13:36:50.913 回答