I want to extract the balance amount from the SMS
my sms content is
account ending with ********9415 has been credited with Rs. 5000. Updated account balance is Rs. 13086.18
Your card transaction of Rs.417 is successful. Your updated credit balance is Rs.78,468
Dear Cardmember, payment of Rs.7657.00 has been received towards your Bank Credit Card ending with 3459 on 12-11-2020 through NEFT. Payment is subject to realisation. Your available Credit limit now is Rs. 173281.31.
This is my code thus far
(?i)(?:\sbalance\s*)([A-Za-z0-9] \s[A-Za-z0-9] )
(?i)(?:\scredit limit\s*)([A-Za-z0-9] \s[A-Za-z0-9] )
Then how to get amount from above SMS?
CodePudding user response:
You can use
(?i)\b(?:balance|credit\s limit)\D (\d (?:[.,]\d )?)
See the regex demo. Details:
(?i)
- case insensitive embedded flag option\b
- a word boundary(?:balance|credit\s limit)
-balance
orcredit limit
with any one or more whitespaces between\D
- one or more non-digit chars(\d (?:[.,]\d )?)
- Group 1 (the value you need to grab): one or more digits, and then an optional sequence of.
or,
and one or more digits. Replace?
with*
if there can be several dots/commas.
See the Java demo:
String regex = "(?i)\\b(?:balance|credit\\s limit)\\D (\\d (?:[.,]\\d )?)";
String text = "account ending with ********9415 has been credited with Rs. 5000. Updated account balance is Rs. 13086.18\n\nYour card transaction of Rs.417 is successful. Your updated credit balance is Rs.78,468\n\nDear Cardmember, payment of Rs.7657.00 has been received towards your Bank Credit Card ending with 3459 on 12-11-2020 through NEFT. Payment is subject to realisation. Your available Credit limit now is Rs. 173281.31.";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(text);
while (matcher.find()){
System.out.println(matcher.group(1));
}
Output:
13086.18
78,468
173281.31
CodePudding user response:
If your data always has that format, you can use a capture group and match the Rs. from the example data: followed by chars a-zA-Z and spaces:
(?i)\b(?:balance|credit\s limit)\s [A-Za-z] (?:\s [A-Za-z] )*\s Rs\.\s*(\d (?:[.,]\d )*)
(?i)
In line modifier for a case insensitive match\b(?:balance|credit\s limit)
match one of 2 alternatives\s [A-Za-z]
Match 1 whitespace chars and 1 chars A-Za-z(?:\s [A-Za-z] )*
Optionally repeat the previous pattern preceded by 1 whitspace chars\s Rs\.\s*
match 1 whitspace chars andRs.
(\d (?:[.,]\d )*)
Capture 1 digits in group 1 optionally repeated by.
or,
and 1 digits
See a regex demo | Java demo.
String regex = "(?i)\\b(?:balance|credit\\s limit)\\s [A-Za-z] (?:\\s [A-Za-z] )*\\s Rs\\.\\s*(\\d (?:[.,]\\d )*)";
String string = "account ending with ********9415 has been credited with Rs. 5000. Updated account balance is Rs. 13086.18\n\n"
"Your card transaction of Rs.417 is successful. Your updated credit balance is Rs.78,468\n\n"
"Dear Cardmember, payment of Rs.7657.00 has been received towards your Bank Credit Card ending with 3459 on 12-11-2020 through NEFT. Payment is subject to realisation. Your available Credit limit now is Rs. 173281.31.";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(string);
while (matcher.find()) {
System.out.println(matcher.group(1));
}
Output
13086.18
78,468
173281.31
CodePudding user response:
It's much better to avoid writing a complicated regexp here. It is easy to make a mistake in it and such mistake would be hard to debug.
What we can do it go for a series of string splits to simplify the problem and turn it into a serie of smaller subproblems.
- First replace the "Rs." substring with say "XXX". We need to do this to remove the dots in
Rs.
so that later.
could be used as a split token. - Split the string on the "." symbol now and save it to array 'sentences'
- For each string in
sentences
array select only everything after the "XXX" part. This will give you the price string "32.12" - Now you just convert it to a number using
Double.valueOf()
It will be much easier to maintain and understand a code like this, rather than code, which uses regexps.