0

I'm trying to replace pi with *pi using the following code, however it throws totally unexpected exception. How is the matcher looking at an index higher then String length?

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)
1
  • It is clear that the length of the string is less than then start value. So its causing the error Commented Mar 25, 2017 at 23:46

2 Answers 2

2

The problem is that you are passing an initial index that is beyond the length of the string in which you are trying to find a match. Method documentation states the following:

Throws: IndexOutOfBoundsException - If start is less than zero or if start is greater than the length of the input sequence.

You need to add a check to see if the initial index is valid:

while (start < sb.length() && m.find(start)) {
    sb.replace(m.start(), m.end(), replacement);
    start = m.start() + replacement.length();
}
Sign up to request clarification or add additional context in comments.

Comments

0

you have a mistake about start position. you can check it. following source code :

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

}

and you'd better write a code. you don't need to make replaceAll Function

 StrBuilder replaceAll(char search, char replace) 

Replaces the search character with the replace character throughout the builder.

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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.