2017-08-03 52 views
0

空间和引号的字符串的子字符串我有以下字符串,并想提取规则的内容,即我的规则说明如下:获取使用的IndexOf

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

当我用我得到以下一个java.lang.StringIndexOutOfBoundsException:字符串索引超出范围:-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异常任何想法?

+2

你调用的东西看起来像'substring(11,4)' – Nathan

+0

你的子串调用不能编译。 –

+0

惊讶没有人提到'“规则\”“+ 7'实际上是字符串'”规则“7”' –

回答

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 

演示在这里:

Rextester

+0

感谢您的解释,我会考虑使用模式。 – Orby

+0

检查其他答案,如果你想看看你在哪里出错了'String#substring()',但如果你的需求比这更复杂,那么正则表达式可能是你的时间更好的投资。 –

0

the documentation

public String substring(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),这属于在异常情况下:

第一个参数比格尔比第二

在你rsecond情况下,使用lastIndexOf,你所得到的第二个引号,这样你就没有这个问题。

+0

这是不正确的。 indexOf的第一个参数是一个字符串;因此,'“rule”“+ 7”实际上是字符串'“rule”7“' –

+0

@MichaelMarkidis因为他得到了一个异常而不是错误,所以你可以假设他写了'String ruleName = rule.substring(rule。 indexOf(“rule \”“)+ 7,rule.indexOf(”\“”));'。 – Nathan

0

indexOf返回指定String的首次出现的索引。

所以你的第一个例子会尝试从索引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的回答