2017-03-25 9 views
0

次のコードを使用してpiを* piに置き換えようとしていますが、予期しない例外が発生します。マッチャーは文字列の長さよりも高いインデックスをどのように見ていますか?StringBuilderのIndexOutOfBoundException

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(); 
     } 
    } 

例外:

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

文字列の長さは、その値を開始以下であることは明らかです。そのため、エラーが発生した –

答えて

2

問題は、あなたが一致を見つけようとしている文字列の長さを超えている最初のインデックスを渡しているということです。メソッドマニュアルには、次のように記載されています。

例外: - startが0より小さいか、startが入力シーケンスの長さより大きい場合。

あなたが最初のインデックスが有効であるかどうかを確認するためのチェックを追加する必要があります。

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

あなたが開始位置についての間違いを持っ​​ています。 あなたはそれをチェックすることができます。次のソースコード:

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); 
} 

}

、あなたがより良いコードを書くと思います。 replaceAll関数を作成する必要はありません。

検索文字をビルダー全体の置換文字に置き換えます。

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)