I am trying to extract values from a given text.
Here is the text:
String 1: $.675.00 was spent on your CAPITAL ONE CREDIT Card ending 2123 on 2015-05-04:15:28:08 at Best Buy
String 2: $ 1,310.00 was spent on your Credit Card 5178XXXXXXXX6040 on MAY-04-15 at Amazon Stores.
I want to extract the following from string:
Amount after $
Credit Card text
Credit card number (in this case - 2123 or 5178XXXXXXXX6040)
at which place (in this case Best Buy or Amazon Stores).
To start I was trying extract all the numbers from the string: I tried the following:
Pattern p = Pattern.compile("\\d+");
Matcher m = p.matcher(string1);
Log.e("Value","from String"+m.group(0));
I am always getting the following error:
05-05 10:09:35.532: E/AndroidRuntime(13618): java.lang.IllegalStateException: No successful match so far
05-05 10:09:35.532: E/AndroidRuntime(13618): at java.util.regex.Matcher.ensureMatch(Matcher.java:471)
05-05 10:09:35.532: E/AndroidRuntime(13618): at java.util.regex.Matcher.group(Matcher.java:578)
Why isn't it matching even though the text has numbers?
Thanks!
As #justhecuke told there is no strict format for your string values to split using Patterns so I did using String functions, give a try
String crType1 = "CREDIT Card ending ";//mind the space at end
String crType2 = "Credit Card ";//mind the space at end
String rate, cardNo, at;
if (string1.contains(crType1)) {
rate = getStringValue(string1, "$", " ");
cardNo = getStringValue(string1, crType1, " ");
at = getAddress(string1);
} else {
rate = getStringValue(string1, "$", " ");
cardNo = getStringValue(string1, crType2, " ");
at = getAddress(string1);
}
System.out.println(String.format("Rate : %s Card No : %s Address : %s", rate, cardNo, at));
Methods
public static String getAddress(String string) {
return string.substring(string.lastIndexOf("at") + 2, string.length()).trim();
}
public static String getStringValue(String string, String startString, String endString) {
int startAt = string.indexOf(startString) + startString.length();
int endAt = string.indexOf(endString, startAt);
return string.substring(startAt, endAt).trim();
}
By the time you call m.group(0) you haven't actually told it to try to match stuff yet. This is why it gives you an IllegalStateException.
Try:
while(m.find()) {
Log.e("Value",String.format("From String: '%s'", m.group()));
}
Related
I've done a bunch of searching but I'm terrible with regex statements and my google-fu in this instance as not been strong.
Scenario:
In push notifications, we're passed a URL that contains a 9-digit content ID.
Example URL: http://www.something.com/foo/bar/Some-title-Goes-here-123456789.html (123456789 is the content ID in this scenario)
Current regex to parse the content ID:
public String getContentIdFromPathAndQueryString(String path, String queryString) {
String contentId = null;
if (StringUtils.isNonEmpty(path)) {
Pattern p = Pattern.compile("([\\d]{9})(?=.html)");
Matcher m = p.matcher(path);
if (m.find()) {
contentId = m.group();
} else if (StringUtils.isNonEmpty(queryString)) {
p = Pattern.compile("(?:contentId=)([\\d]{9})(?=.html)");
m = p.matcher(queryString);
if (m.find()) {
contentId = m.group();
}
}
}
Log.d(LOG_TAG, "Content id " + (contentId == null ? "not found" : (" found - " + contentId)));
if (StringUtils.isEmpty(contentId)) {
Answers.getInstance().logCustom(new CustomEvent("eid_url")
.putCustomAttribute("contentId", "empty")
.putCustomAttribute("path", path)
.putCustomAttribute("query", queryString));
}
return contentId;
}
The problem:
This does the job but there's a specific error scenario that I need to account for.
Whoever creates the push may put in the wrong length content ID and we need to grab it regardless of that, so assume it can be any number of digits... the title can also contain digits, which is annoying. The content ID will ALWAYS be followed by ".html"
While the basic answer here would be just "replace {9} limiting quantifier matching exactly 9 occurrences with a + quantifier matching 1+ occurrences", there are two patterns that can be improved.
The unescaped dot should be escaped in the pattern to match a literal dot.
If you have no overlapping matches, no need to use a positive lookahead with a capturing group before it, just keep the capturing group and grab .group(1) value.
A non-capturing group (?:...) is still a consuming pattern, and the (?:contentId=) equals contentId= (you may remove (?: and )).
There is no need wrapping a single atom within a character class, use \\d instead of [\\d]. That [\\d] is actually a source of misunderstandings, some may think it is a grouping construct, and might try adding alternative sequences into the square brackets, while [...] matches a single char.
So, your code can look like
Pattern p = Pattern.compile("(\\d+)\\.html"); // No lookahead, + instead of {9}
Matcher m = p.matcher(path);
if (m.find()) {
contentId = m.group(1); // (1) refers to Group 1
} else if (StringUtils.isNonEmpty(queryString)) {
p = Pattern.compile("contentId=(\\d+)\\.html");
m = p.matcher(queryString);
if (m.find()) {
contentId = m.group(1);
}
}
I am fetching number from contact book and sending it to server. i get number like this (+91)942 80-60 135 but i want result like this +9428060135.+ must be first character of string number.
Given your example you want to replace the prefix with a single + character. You also want to remove other non-numeric characters from the number string. Here's how you can do that:
String number = "(+91)942 80-60 135";
number = "+" + number.replaceAll("\\(\\+\\d+\\)|[^\\d]", "");
The regex matches any prefix (left paren followed by a + followed by one or more digits, followed by a right paren) or any non digit character, and removes them. This is concatenated to a leading + as required. This code will also handle + characters within the number string, e.g. +9428060135+++ and +(+91)9428060135+++.
If you simply wanted to remove any character that is not a digit nor a +, the code would be:
String number = "(+91)942 80-60 135";
number = number.replaceAll("[^\\d+]", "");
but be aware that this will retain the digits in the prefix, which is not the same as your example.
You can use String.replace(oldChar, newChar). Use the code below
String phone = "(+91)942 80-60 135"; // fetched string
String trimmedPhone = phone.replace("(","").replace(")","").replace("-","").trim();
I hope it will work for you.
check this. Pass your string to this function or use as per code goes
String inputString = "(+91)942 80-60 135";
public void removeSpecialCharacter(String inputString) {
String replaced = inputString.replaceAll("[(\\-)]", "");
String finalString = replaced.replaceAll(" ", "");
Log.e("String Output", " " + replaced + " " + second);
}
The regex
.*([0-9]{3}\\.[0-9]{2}).*
finds one match in "some short sentence 111.01 ", but it failed to match the first occurrence "111.01" in "some short sentence 111.01 & 222.02 "
I tried the lazy quantifier .*([0-9]{3}\\.[0-9]{2})?.* or .*([0-9]{3}\\.[0-9]{2}).*? for no avail.
Please help, I need to get both occurrences, here is my code.
Thank you
Pattern myPattern = Pattern.compile(".*([0-9]{3}\\.[0-9]{2}).*");
Matcher m = myPattern.matcher(mystring);
while (m.find()) {
String found = m.group(1);
}
you need to remove ".*"s. Try this:
String mystring = "some short sentence 111.01 & 222.02 ";
Pattern myPattern = Pattern.compile("([0-9]{3}\\.[0-9]{2})");
Matcher m = myPattern.matcher(mystring);
while(m.find()) {
System.out.println("Found value: " + m.group(1) );
}
output:
Found value: 111.01
Found value: 222.02
The leading and trailing ".*" cause you to match the entire string in one match. All the lazy quantifier does in your case is controls you getting the first, not last, occurrence in the subject.
I try to get only this part "9916-4203" in "Region Code:9916-4203 " in android. How can I do this?
I tried below code, I used substring method but it doesn't work:
firstNumber = Integer.parseInt(message.substring(11, 19));
If you know that string contains "Region Code:" couldn't you do a replace?
message = message.replace("Region Code:", "");
Assumed that you have only one phone number in your String, the following will remove any non-digit characters and parse the resulting number:
public static int getNumber(String num){
String tmp = "";
for(int i=0;i<num.length();i++){
if(Character.isDigit(num.charAt(i)))
tmp += num.charAt(i);
}
return Integer.parseInt(tmp);
}
Output in your case: 99164203
And as already mentioned, you won't be able to parse any String to Integer in case there are any non-digit characters
Im going to guess that what you want to extract is the full region code text minus the title. So maybe using regex would be a good simple fit for you?
String myString = "Region Code:9916-4203";
String match = "";
String pattern = "\:(.*)";
Pattern regEx = Pattern.compile(pattern);
Matcher m = regEx.matcher(myString);
// Find instance of pattern matches
Matcher m = regEx.matcher(myString);
if (m.find()) {
match = m.group(0);
}
Variable match will contain "9916-4203"
This should work for you.
Java code sourced from http://android-elements.blogspot.in/2011/04/regular-expressions-in-android.html
In Java the substring() method works with the first parameter being inclusive and the second parameter being exclusive. Meaning "Hello".substring(0, 2); will result in the string He.
In addition to excluding the parsing of something that isn't a number like #Opiatefuchs mentioned, your substring method should instead be message.substring(12, 21).
I have a number that I need to format as a telephone number. If I do
PhoneNumberUtils.formatNumber(numStr);
Then I get
888-555-1234
But what I need to get is
(888) 555-1234
How do I get the second one? Is there a standard android way?
If you know the country for which you want to do it, you can use Google's open source library libphonenumber . Here is how you can format it:
String numberStr = "8885551234"
PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
try {
PhoneNumber numberProto = phoneUtil.parse(numberStr, "US");
//Since you know the country you can format it as follows:
System.out.println(phoneUtil.format(numberProto, PhoneNumberFormat.NATIONAL));
} catch (NumberParseException e) {
System.err.println("NumberParseException was thrown: " + e.toString());
}
If you don't know the country then for numberStr use E.164 format phone number and in place of country code use null.
Don't know if you found what you were looking for, but I ended up writing a little method that takes the length of a string (since the phone numbers I get come from a web service and can be a variety of formats). I believe it should work (so far all my test cases have been with the first two options -- haven't tested the other two yet).
public static String FormatStringAsPhoneNumber(String input) {
String output;
switch (input.length()) {
case 7:
output = String.format("%s-%s", input.substring(0,3), input.substring(3,7));
break;
case 10:
output = String.format("(%s) %s-%s", input.substring(0,3), input.substring(3,6), input.substring(6,10));
break;
case 11:
output = String.format("%s (%s) %s-%s", input.substring(0,1) ,input.substring(1,4), input.substring(4,7), input.substring(7,11));
break;
case 12:
output = String.format("+%s (%s) %s-%s", input.substring(0,2) ,input.substring(2,5), input.substring(5,8), input.substring(8,12));
break;
default:
return null;
}
return output;
}
If you have the String "888-555-1234" - by using PhoneNumberUtils.formatNumber(numStr); you can simply do this:
String numStr = "888-555-1234";
numStr = "(" + numStr.substring(0,3) + ") " + numStr.substring(4);
System.out.print(numStr); // (888) 555-1234
However, this is hard coded. You would need to make sure the String had a full 10 digits before doing so.
You simply use this and get you want :
new PhoneNumberFormattingTextWatcher()
or Have look at this url :
http://developer.android.com/reference/android/telephony/PhoneNumberFormattingTextWatcher.html
Try to use regex. This will help you. As for me, i use this:
var result = "+1 888-555-1234"
if (Pattern.compile("^\\+[\\d]+\\s[\\d]{1,3}\\s[\\d]+").matcher(result).find()) {
result = result.replaceFirst(" ", "(").replaceFirst(" ", ")").replace(" ","-")
}
if(Pattern.compile("^\\+[\\d]+\\s[\\d]{1,3}-[\\d]+").matcher(result).find()){
result = result.replaceFirst(" ", "(").replaceFirst("-", ")")
}
Timber.d("$result")
output: +1(888)555-1234
Working solution in 2020:
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
String countryIso = telephonyManager.getNetworkCountryIso().toUpperCase();
phoneNumberTextView.setText(PhoneNumberUtils.formatNumber("3473214567", countryIso));