2017-03-25 2 views
0

J'essaie de remplacer pi par * pi en utilisant le code suivant, mais il renvoie une exception totalement inattendue. Comment le comparateur regarde-t-il un index plus haut que la longueur de la chaîne?IndexOutOfBoundException sur StringBuilder

private void makeEvaluationStringExpressionMXParserCompliant() { 
     Pattern multiply = Pattern.compile(mContext.getString(R.string.string_multiply)); 
     Pattern pi = Pattern.compile(mContext.getString(R.string.string_pie)); 
     Pattern e = Pattern.compile(mContext.getString(R.string.string_e)); 

     Log.e("wingoku", "pi: "+ pi.toString() + " completeString: "+ mEvaluationStringExpressionBuilder.toString()); 

     replaceAll(mEvaluationStringExpressionBuilder, pi, "*pi"); 
    } 

    private void replaceAll(StringBuilder sb, Pattern pattern, String replacement) { 
     Matcher m = pattern.matcher(sb); 
     int start = 0; 
     while (m.find(start)) { 
      sb.replace(m.start(), m.end(), replacement); 
      start = m.start() + replacement.length(); 
     } 
    } 

Exception:

java.lang.IndexOutOfBoundsException: start=3; length=2 
                at java.util.regex.Matcher.find(Matcher.java:339) 
                at com.app.calculator.utils.StringExpressionFactory.replaceAll(StringExpressionFactory.java:68) 
                at com.app.calculator.utils.StringExpressionFactory.makeEvaluationStringExpressionMXParserCompliant(StringExpressionFactory.java:61) 
                at com.app.calculator.utils.StringExpressionFactory.createExpression(StringExpressionFactory.java:31) 
+0

Il est clair que la longueur de la chaîne est inférieure à la valeur alors commencer. Donc c'est l'erreur –

Répondre

2

Le problème est que vous passez un index initial qui est au-delà de la longueur de la chaîne dans laquelle vous essayez de trouver un match. états de documentation de la méthode qui suit:

Génère: IndexOutOfBoundsException - Si le démarrage est inférieur à zéro ou si le démarrage est supérieure à la longueur de la séquence d'entrée.

Vous devez ajouter un contrôle pour voir si l'indice initial est valide:

while (start < sb.length() && m.find(start)) { 
    sb.replace(m.start(), m.end(), replacement); 
    start = m.start() + replacement.length(); 
} 
0

vous avez une erreur sur la position de départ. vous pouvez le vérifier. suivant le code source:

public static void replaceAll(StringBuilder sb, Pattern pattern, String replacement) { 
Matcher m = pattern.matcher(sb); 
while(m.find()) { 
    sb.replace(m.start(), m.end(), replacement); 
} 

}

et vous feriez mieux d'écrire un code. Vous n'avez pas besoin de remplacer la fonction Tout remplacer

StrBuilder replaceAll(char search, char replace) 

Remplace le caractère de recherche par le caractère de remplacement dans l'ensemble du générateur.

https://commons.apache.org/proper/commons-lang/javadocs/api-3.1/org/apache/commons/lang3/text/StrBuilder.html#replaceAll(java.lang.String,%20java.lang.String)