Java 字符串索引超出范围 '}' 标记不正确 inluded/printing
Java String index out of range '}' token not inluded/printing properly
我目前有这段代码,除了“}”标记外都可以使用。
如果我输入
WOrd 023 {dOor "knob!"}
输出为
`WOrd 023 {dOor "knob!"}
WOrd
word
main.WordToken@33909752
023
23
main.NumberToken@55f96302
{
main.StartToken@3d4eac69
dOor
door
main.WordToken@42a57993
knob!
main.QuoteToken@75b84c92
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: -1
at java.lang.String.substring(Unknown Source)
at main.ScannerBean.scan(ScannerBean.java:85)
at main.Assignment3.main(Assignment3.java:11)`
我很确定 startIndex 或 endIndex 有问题,但到目前为止我几乎没有做任何改进。对于其他输入,错误不会出现,但 '}' 仍然不会按应有的方式打印。我还注意到“-”和“+”标记也没有打印。原文:
package main;
public class ScannerBean implements TokenInterface, ScannerBeanInterface{
String Input;
public ScannerBean(String Input){
this.Input = Input;
}
public String getInput(){
return Input;
}
public void setInput(String Input){
this.Input = Input;
}
public void scan() {
int startIndex = 0;
int stopIndex = 0;
String mySubstring = "";
boolean isQuote = false;
while (++stopIndex < Input.length()) {
if (startIndex >= Input.length()) {
break;
}
if (Input.charAt(startIndex) == '"' || isQuote) {
isQuote = true;
if (stopIndex + 1 < Input.length() && Input.charAt(stopIndex + 1) == '"') {
mySubstring = Input.substring(startIndex+1, stopIndex+1);
isQuote = false;
startIndex = stopIndex + 2;
TokenInterface tt=new QuoteToken(mySubstring);
System.out.println(tt.getInput());
TokenInterface quoteToken = new QuoteToken(mySubstring);
System.out.println(quoteToken.toString());
}
}
else if (Character.isLetter(Input.charAt(startIndex))){
if (!Character.isLetter(Input.charAt(stopIndex)) || Input.charAt(stopIndex) == '}'){
mySubstring = Input.substring(startIndex, stopIndex);
startIndex = stopIndex + 1;
TokenInterface tt=new WordToken(mySubstring);
System.out.println(tt.getInput());
WordTokenInterface w = new WordToken(mySubstring);
System.out.println(w.getValue());
System.out.println(w.toString());
}
}
else if (Character.isDigit(Input.charAt(startIndex))){
if(!Character.isDigit(Input.charAt(stopIndex))){
mySubstring = Input.substring(startIndex, stopIndex);
startIndex = stopIndex + 1;
TokenInterface tt=new NumberToken(mySubstring);
System.out.println(tt.getInput());
NumberTokenInterface n = new NumberToken(mySubstring);
System.out.println(n.getValue());
System.out.println(n.toString());
}
}
else if (Input.charAt(startIndex) == '{'){
if(Input.charAt(stopIndex) != '{') {
mySubstring = Input.substring(startIndex, stopIndex);
startIndex = stopIndex;
TokenInterface tt=new StartToken(mySubstring);
System.out.println(tt.getInput());
TokenInterface startToken = new StartToken(mySubstring);
System.out.println(startToken.toString());
}
}
else if (Input.charAt(startIndex) == '}'){
if(Input.charAt(stopIndex) != '}') {
mySubstring = Input.substring(startIndex, stopIndex);
startIndex = stopIndex;
TokenInterface tt=new EndToken(mySubstring);
System.out.println(tt.getInput());
TokenInterface endToken = new EndToken(mySubstring);
System.out.println(endToken.toString());
}
}
else if (Input.charAt(startIndex) == '-'){
if(Input.charAt(startIndex) != '-' ){
mySubstring = Input.substring(startIndex, startIndex+1);
startIndex = stopIndex;
TokenInterface tt=new MinusToken(mySubstring);
System.out.println(tt.getInput());
TokenInterface minusToken = new MinusToken(mySubstring);
System.out.println(minusToken.toString());
}
}
else if (Input.charAt(startIndex) == '+'){
if(Input.charAt(startIndex) != '+' ){
mySubstring = Input.substring(startIndex,stopIndex);
startIndex = stopIndex + 1;
TokenInterface tt=new PlusToken(mySubstring);
System.out.println(tt.getInput());
TokenInterface plusToken = new PlusToken(mySubstring);
System.out.println(plusToken.toString());
}
}
else if (Input.charAt(stopIndex) == ' '){
startIndex++;
}
}
}
}
当你在这里得到子串时
else if (Input.charAt(startIndex) == '}'){
if(Input.charAt(stopIndex) != '}') {
mySubstring = Input.substring(startIndex, stopIndex);
startIndex
大于 stopIndex
。我建议使用 java.util.Scanner
重写整个内容,除非有一些你不能或不想这样做的充分理由。
您可以使用其 findWithinHorizon(Pattern, int)
方法为您完成大部分工作,前提是您提供正确的 Pattern
s。不过,在使用 next...()
方法时要小心 - 它们总是采用完整的标记(两边用定界符分隔),这不是你想要的,除非你更改定界符。
这是一个关于如何使用它的简单示例:
static final Pattern WORD = Pattern.compile("\G[a-zA-Z]+");
static final Pattern NUMBER = Pattern.compile("\G\d+");
static final Pattern LEFT = Pattern.compile("\G\{");
static final Pattern RIGHT = Pattern.compile("\G\}");
static final Pattern QUOTES = Pattern.compile("\G\"");
static final Pattern QUOTED_CHARS = Pattern.compile("\G[^\"]*");
static final Pattern WHITESPACE = Pattern.compile("\G\s*");
public static void main(String[] args) {
String s = "WOrd 023 \"\"{dOor \"knob!\"}";
Scanner sc = new Scanner(s);
while (true) {
sc.skip(WHITESPACE);
if (!sc.hasNext()) {
break;
}
String token;
if ((token = sc.findWithinHorizon(WORD, 0)) != null) {
System.out.println("word: " + token);
} else if ((token = sc.findWithinHorizon(NUMBER, 0)) != null) {
System.out.println("number: " + token);
} else if ((token = sc.findWithinHorizon(LEFT, 0)) != null) {
System.out.println("left: " + token);
} else if ((token = sc.findWithinHorizon(RIGHT, 0)) != null) {
System.out.println("right: " + token);
} else if ((token = sc.findWithinHorizon(QUOTES, 0)) != null) {
token = sc.findWithinHorizon(QUOTED_CHARS, 0);
System.out.println("quoted: '" + token + "'");
sc.findWithinHorizon(QUOTES, 0);
}
}
}
详情请看这里:
http://docs.oracle.com/javase/8/docs/api/java/util/Scanner.html
http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html
我目前有这段代码,除了“}”标记外都可以使用。 如果我输入
WOrd 023 {dOor "knob!"}
输出为
`WOrd 023 {dOor "knob!"}
WOrd
word
main.WordToken@33909752
023
23
main.NumberToken@55f96302
{
main.StartToken@3d4eac69
dOor
door
main.WordToken@42a57993
knob!
main.QuoteToken@75b84c92
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: -1
at java.lang.String.substring(Unknown Source)
at main.ScannerBean.scan(ScannerBean.java:85)
at main.Assignment3.main(Assignment3.java:11)`
我很确定 startIndex 或 endIndex 有问题,但到目前为止我几乎没有做任何改进。对于其他输入,错误不会出现,但 '}' 仍然不会按应有的方式打印。我还注意到“-”和“+”标记也没有打印。原文:
package main;
public class ScannerBean implements TokenInterface, ScannerBeanInterface{
String Input;
public ScannerBean(String Input){
this.Input = Input;
}
public String getInput(){
return Input;
}
public void setInput(String Input){
this.Input = Input;
}
public void scan() {
int startIndex = 0;
int stopIndex = 0;
String mySubstring = "";
boolean isQuote = false;
while (++stopIndex < Input.length()) {
if (startIndex >= Input.length()) {
break;
}
if (Input.charAt(startIndex) == '"' || isQuote) {
isQuote = true;
if (stopIndex + 1 < Input.length() && Input.charAt(stopIndex + 1) == '"') {
mySubstring = Input.substring(startIndex+1, stopIndex+1);
isQuote = false;
startIndex = stopIndex + 2;
TokenInterface tt=new QuoteToken(mySubstring);
System.out.println(tt.getInput());
TokenInterface quoteToken = new QuoteToken(mySubstring);
System.out.println(quoteToken.toString());
}
}
else if (Character.isLetter(Input.charAt(startIndex))){
if (!Character.isLetter(Input.charAt(stopIndex)) || Input.charAt(stopIndex) == '}'){
mySubstring = Input.substring(startIndex, stopIndex);
startIndex = stopIndex + 1;
TokenInterface tt=new WordToken(mySubstring);
System.out.println(tt.getInput());
WordTokenInterface w = new WordToken(mySubstring);
System.out.println(w.getValue());
System.out.println(w.toString());
}
}
else if (Character.isDigit(Input.charAt(startIndex))){
if(!Character.isDigit(Input.charAt(stopIndex))){
mySubstring = Input.substring(startIndex, stopIndex);
startIndex = stopIndex + 1;
TokenInterface tt=new NumberToken(mySubstring);
System.out.println(tt.getInput());
NumberTokenInterface n = new NumberToken(mySubstring);
System.out.println(n.getValue());
System.out.println(n.toString());
}
}
else if (Input.charAt(startIndex) == '{'){
if(Input.charAt(stopIndex) != '{') {
mySubstring = Input.substring(startIndex, stopIndex);
startIndex = stopIndex;
TokenInterface tt=new StartToken(mySubstring);
System.out.println(tt.getInput());
TokenInterface startToken = new StartToken(mySubstring);
System.out.println(startToken.toString());
}
}
else if (Input.charAt(startIndex) == '}'){
if(Input.charAt(stopIndex) != '}') {
mySubstring = Input.substring(startIndex, stopIndex);
startIndex = stopIndex;
TokenInterface tt=new EndToken(mySubstring);
System.out.println(tt.getInput());
TokenInterface endToken = new EndToken(mySubstring);
System.out.println(endToken.toString());
}
}
else if (Input.charAt(startIndex) == '-'){
if(Input.charAt(startIndex) != '-' ){
mySubstring = Input.substring(startIndex, startIndex+1);
startIndex = stopIndex;
TokenInterface tt=new MinusToken(mySubstring);
System.out.println(tt.getInput());
TokenInterface minusToken = new MinusToken(mySubstring);
System.out.println(minusToken.toString());
}
}
else if (Input.charAt(startIndex) == '+'){
if(Input.charAt(startIndex) != '+' ){
mySubstring = Input.substring(startIndex,stopIndex);
startIndex = stopIndex + 1;
TokenInterface tt=new PlusToken(mySubstring);
System.out.println(tt.getInput());
TokenInterface plusToken = new PlusToken(mySubstring);
System.out.println(plusToken.toString());
}
}
else if (Input.charAt(stopIndex) == ' '){
startIndex++;
}
}
}
}
当你在这里得到子串时
else if (Input.charAt(startIndex) == '}'){
if(Input.charAt(stopIndex) != '}') {
mySubstring = Input.substring(startIndex, stopIndex);
startIndex
大于 stopIndex
。我建议使用 java.util.Scanner
重写整个内容,除非有一些你不能或不想这样做的充分理由。
您可以使用其 findWithinHorizon(Pattern, int)
方法为您完成大部分工作,前提是您提供正确的 Pattern
s。不过,在使用 next...()
方法时要小心 - 它们总是采用完整的标记(两边用定界符分隔),这不是你想要的,除非你更改定界符。
这是一个关于如何使用它的简单示例:
static final Pattern WORD = Pattern.compile("\G[a-zA-Z]+");
static final Pattern NUMBER = Pattern.compile("\G\d+");
static final Pattern LEFT = Pattern.compile("\G\{");
static final Pattern RIGHT = Pattern.compile("\G\}");
static final Pattern QUOTES = Pattern.compile("\G\"");
static final Pattern QUOTED_CHARS = Pattern.compile("\G[^\"]*");
static final Pattern WHITESPACE = Pattern.compile("\G\s*");
public static void main(String[] args) {
String s = "WOrd 023 \"\"{dOor \"knob!\"}";
Scanner sc = new Scanner(s);
while (true) {
sc.skip(WHITESPACE);
if (!sc.hasNext()) {
break;
}
String token;
if ((token = sc.findWithinHorizon(WORD, 0)) != null) {
System.out.println("word: " + token);
} else if ((token = sc.findWithinHorizon(NUMBER, 0)) != null) {
System.out.println("number: " + token);
} else if ((token = sc.findWithinHorizon(LEFT, 0)) != null) {
System.out.println("left: " + token);
} else if ((token = sc.findWithinHorizon(RIGHT, 0)) != null) {
System.out.println("right: " + token);
} else if ((token = sc.findWithinHorizon(QUOTES, 0)) != null) {
token = sc.findWithinHorizon(QUOTED_CHARS, 0);
System.out.println("quoted: '" + token + "'");
sc.findWithinHorizon(QUOTES, 0);
}
}
}
详情请看这里:
http://docs.oracle.com/javase/8/docs/api/java/util/Scanner.html
http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html