1

I have a string that starts with 7 characters (let's say XXXXXXX) and after that there are 8 characters that represnet a decimal number. For example: XXXXXXX30.00000 would be 30.00 (I want 2 decimal places) So it should start on index 7 read until dot (.) + 2 decimal places. It should be a string, not a number. I tried with string.substring() but got stuck here.

ADM
  • 20,406
  • 11
  • 52
  • 83
GeoCap
  • 505
  • 5
  • 15

2 Answers2

1

First you can remove the first 7 characters by

var newString = yourString.removeRange(0,6)

then you can cast to a double if you're certain it will always be a number

var yourNumber = newString.ToDouble()

If you're not sure you can wrap in a try/catch eg:

    try{
        var yourNumber = newString.ToDouble()
    }catch(e:TypeCastException){
       println("Failed to cast to double - "+ e.message)
    }

additionally, to round to a 2 decimal places:

val number2digits:Double = String.format("%.2f", yourNumber).toDouble()
nt95
  • 455
  • 1
  • 6
  • 21
  • It rounds it, but doesn't return two zeroes: 30.0 instead of 30.00 – GeoCap Sep 12 '20 at 14:49
  • Remember that [floating-point numbers are not precise](https://stackoverflow.com/questions/588004/is-floating-point-math-broken/588014).  (Or rather, they're precise for binary fractions, but not for decimal fractions as in this question.)  If you need precision, consider storing as a [BigDecimal](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/java.math.-big-decimal/), a scaled integer, or even a String. – gidds Sep 12 '20 at 15:45
0

I suggest you do it using the regex, [A-Za-z]{8}(\d+.\d{2})

Explanation of the regex:

  1. [A-Za-z]{8} specifies 8 characters. If you want to support characters other than English alphabets, you can replace [A-Za-z] with \p{L} which specifies unicode letters.
  2. (\d+.\d{2}) specifies a capturing group consisting of digits followed by . which in turn should be followed by 2 digits as per your requirement. A regex pattern can have more than one capturing groups. Since it is the first capturing group in this pattern, it can be accessed by group(1).

A test code:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {
    public static void main(String[] args) {
        // Some test strings
        String[] arr = { "abcdefgh30.00000", "abcdefgh300.0000", "abcdefgh3000.00", "abcdefgh3.00000",
                "abcdefgh0.05000" };
        Pattern pattern = Pattern.compile("[A-Za-z]{8}(\\d+.\\d{2})");
        for (String s : arr) {
            Matcher matcher = pattern.matcher(s);
            if (matcher.find()) {
                String str = matcher.group(1);
                System.out.println(str);
            }
        }
    }
}

Output:

30.00
300.00
3000.00
3.00
0.05
Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110