Regex to determine if string contains at least 2 numbers - android

I'm try to write a username field validator and one of the reqs is that the field must contain at least 2 numbers (more is ok, just no less). I thought I could do something like this, and the regex splits on the first number, but never on the second.
String[] arr = string.split("[0-9][0-9]");
return arr.length > 2;
Use cases:
Bob11
Bo1b1
11Bob
1Bob1

Below is my version, that has an extremely fast execution, can be easily updated to different criteria, and has a better readability (at least to me):
Regex
(\D*\d){2,}
Example
Bob11 - Match
Bo1b1 - Match
11Bob - Match
1Bob1 - Match
11235 - Match
Bobb - Does NOT Match
Bob1 - Does NOT Match
Bo1b - Does NOT Match
1Bob - Does NOT Match
Explanation
\D - non digit.
* - (quantifier) zero or more times.
\d - one digit.
(\D*\d) - encapsulate the combination above as a group.
{2,} - (quantifier) ensures that the group occurs at least 2 times, being able to occur more times.
(\D*\d){2,} - So, \D* non digit zero or infinite times, followed by a \d digit, this combination repeated {2,} two or infinite times.
Updating to different criteria
The ^ (start string anchor) and $ (end string anchor) can be included to ensure restriction, in case the criteria changes to be exact 2 or any other number.
This is an example that ensures no more, no less that 5 numbers anywhere in a string: ^(\D*\d){5}\D*$. The last \D is necessary to allow the string to end with a non digit, validating the regex if the criteria of five digits be satisfied.*

Try this:
.* matches everything (from 0 to n times)
[0-9] is number from 0-9
Pattern pattern = Pattern.compile("[0-9].*[0-9]");
Matcher matcher = pattern.matcher(string);
if (matcher.find()) {
return true;
}
And you can check regex in https://www.freeformatter.com/regex-tester.html

Remove all non numeric characters using regex and count the length

[^\d]*\d[^\d]*\d.* should be one way to go (there are several..)
[^\d]* Matches any character which is not a digit (zero to infinite times)
\d matches a single digit (once)
.* matches everything (zero to infinite times)
I use [^\d]* because .* is greedy and thus might match too much (depending on the language). Greedy behavior can be disabled by appending ?: .*?
You can test it at https://regex101.com/.

You do not need RegEx for this. I'm not sure what language you're using, but it is safe to assume that a String in your language is essentially a Char array. If that is the case, then get the count of digit characters in the Char array and compare if it is greater than 1.
For example, here is a C# example:
String username = Console.ReadLine();
if (username.Count(c => Char.IsDigit(c)) > 1) {
Console.WriteLine("The String contains 2 or more digits.");
} else {
Console.WriteLine("The String did not contain 2 or more digits.");
}
This would likely yield faster results too.

Use string.match(‘.*\d.*\d.*’);
It will look for one digit two times in a string.

Related

Android: regex for edit text to have only 2 values possible in decimal

In my filter used into EditText, I want to be sure the user can only set .5 or .0 for decimal values.
Valid values examples:
34.5
34.0
34
Invalid values examples:
34.2
34.8
34.6
I tried this one, but it doesn't work properly: [0-9]*[.]?[0|5]
Thank you very much guys!
You're probably looking for [0-9]*(\.([50][0]*)*)*.
[0-9]*: Any character from 0 to 9, zero or more times [so that just a "." (= 0.0) input is valid]
\.: You need to escape the '.' character, since it usually would mean "any character", and you especifically need the dot there.
[50][0]*: First, either five or zero (once). Second, the 0 character, zero or more times (since 35.50 = 35.5). This also avoids inputs like 35.59 from being valid, since 9 != 0.
([50][0]*)*: This occurrence zero or more times, so that 35., for instance, becomes a valid input (since 35. = 35.0).
(\.([50][0]*)*)*: As for this grouping, it's in order to check for the five or the zero only if there is a decimal dot. It's grouping the dot character and the 5/0 logic together with a star (zero or more times) at the end, so if it doesn't occur, it still matches.
Let me know if this was what you were looking for.
To verify the whole numbers in the examples, you can make the last part optional and use anchors.
^[0-9]+(?:[.][05])?$
^ Start of string
[0-9]+ Match 1+ digits 0-9
(?:[.][05])? Optionally match . and a digit 0 or 5
$ End of string
See a regex demo.
If you want to be able to only type a pattern like that and also accept empty strings or 34. you can repeat the digit 0 or more times, optionally match . and optionally match either 0 or 5.
^[0-9]*[.]?[05]?$
See another regex demo

How to pass multiple delimiters to a substring (Kotlin/Android)?

I'm trying to make a calculator app, and I need to be able to get the last value after someone presses an operator (+,*,-,/) after the second time (the first value is saved with no issues since it's the only number on the screen).
So if the top of the screen has something like (222 * 3333 / 12), I need to get 12. Once I learn how to do this, I can figure out how to save the previous number/sum, then do calculations on the next number (I haven't made that part yet though).
I know this is a janky way of doing things, and any suggestions are appreciated.
So I can grab this number if I use substringAfterLast() and insert an operator there, however, if mix things up and use multiple operators (like 222 * 3333 / 12), my y variable (see below) just shows "222 * 3333 / 12" instead of 12.
How can I use multiple delimiters for substring?
Here's my code by the way (forgive me)
multiplybutton.setOnClickListener {
var x = numbersEntered.toString()
var y = ""
//creates an array that holds the operators so it can be easily filtered out
val operators = arrayOf<Char>('*','/','+','-')
//prevents app from crashing by saving the last value before the operator is added, allowing us to create infinite number of operations
if (x.any(operators :: contains)){
// x.split(operators.toString())
y = x.substringAfterLast('*') // can't use my operator character array here? why? how do I iterate through it?
Toast.makeText(this, y.toString(), Toast.LENGTH_SHORT).show()
// previousvalue = y.toInt()
} else {
previousvalue = x.toInt()
}
numbersEntered.append("*")
numbersEnteredBox.setText(numbersEntered.toString())
isMultiply = true;
Toast.makeText(this, previousvalue.toString(), Toast.LENGTH_SHORT).show()
}
edit: ignore italics plz, not sure what went wrong
sorry, maybe I not fully understand what you want to do but you can use split function to get last number from string like this 222 * 3333 / 12:
println("222 * 3333 / 12".split('+', '-', '*', '/').last().trim().toInt())
// prints 12
Use split with a regular expression
Using a regular expression gives you a great deal of control over how the string is split. In your case, anything that isn't a numeric digit is probably a delimiter. Regex has a built-in character class, denoted by \D, that will match any character that isn't a digit.
val pattern = Regex("""\D+""") // matches one or more non-digit characters
"1 * 2 / 3".split(pattern).last() // returns "3"
Equally, you could create your own character class, using [], to be more specific about which characters you want to use as delimiters:
val pattern = Regex("""\s*[-\+*]\s*""") // matches -\+*, and any spaces around them
"1 * 2 / 3".split(pattern).last() // returns "3"

Check if part of text matches a regex

I'm trying to build a component similar to Google Play's credit card adding:
Where the user starts typing the credit card number, and only the credit card images that stay visible, are of the cards that matches part of the credit card number pattern.
For example:
Looking at MasterCard regex: ^5[1-5][0-9]{14}$
If the user type "5", "53", "531", the image of master card should be visible.
I guess it can be done with Pattern and Matcher class, but how?
Using match() method is not good, as it trying to match against all the pattern.
Thanks in advance!
If you want a pattern for live validation, you can use
^5([1-5][0-9]{0,14})?$
See the regex demo.
Note you cannot use it for final string validation, you will have to use your current regex for it.
The main thing about a regex for live input validation is that it allows the next character only if the previous one matches, and that is possible with nested optional groups. Since you have only 3 parts: 1) the first obligatory 5, then 1 to 5 digit, and then any 0 to 14 digits, you may use just one optional group around [1-5][0-9]{0,14} pattern and and make sure you allow zero or up to 14 other digits.
Details:
^ - start of string
5 - obligatory 5
([1-5][0-9]{0,14})? - an optional sequence (1 or 0 occurrences) of:
[1-5] - a digit from 1 to 5
[0-9]{0,14} - any zero to forteen digits
$ - end of string.
Use your pattern for activation the buttonand this for the image
^5[1-5][0-9]{0, 14}$

Password validator is not working in android

In my application I am accepting a password from the user which should be in following format:-
case sensitive and
must be at least 6 characters long,
including at least
one letter (a-Z),
one number (0-9) and
one of the following special characters:!=+*;:-,._{[()]}#%?#
So by following the tutorial given here:
http://www.mkyong.com/regular-expressions/how-to-validate-password-with-regular-expression/
I have created my own pattern as:-
private static final String PASSWORD_PATTERN = "($\\S*(?=\\S{6,})(?=\\S*[a-z])(?=\\S*[A-Z])(?=\\S*[\\d])(?=\\S*[\\W])\\S*$)";
But it is not working properly. If I enter a correct value for the password as per pattern, it still displays an error to me.
Please tell me what's happening here; what error is there?
Here is my code:-
PWD_Validate = new PasswordValidator();
String password = TXT_PassWord.getText().toString();
if (PWD_Validate.validate(password))
{
}
else{ } it takes me every time in else block, even I entered a correct passwaord.
I'm not sure why you've deviated from the pattern that is listed within the tutorial you've linked. Your pattern starts with $ which asserts position at end of the string, so it's highly unlikely you'll match anything. Usually if you're using an assertion you use $ at the very end of the pattern and ^ to assert the beginning.
Also no where in your pattern do you have any of the special characters you've outlined as those you've said are required. If you plan on matching those I would recommend including them into your pattern.
The breakdown of your regex goes like this:
$ assert position at end of the string (you've got it at the beginning).
\S* match any non-white space character [^\r\n\t\f ]
Quantifier: Between zero and unlimited times, as many times as possible, giving back as needed [greedy]
(?=\S{6,}) Positive Lookahead - Assert that the regex below can be matched
\S{6,} match any non-white space character [^\r\n\t\f ]
Quantifier: Between 6 and unlimited times, as many times as possible, giving back as needed [greedy]
(?=\S*[a-z]) Positive Lookahead - Assert that the regex below can be matched
\S* match any non-white space character [^\r\n\t\f ]
Quantifier: Between zero and unlimited times, as many times as possible, giving back as needed [greedy]
[a-z] match a single character present in the list below
a-z a single character in the range between a and z (case sensitive)
(?=\S*[A-Z]) Positive Lookahead - Assert that the regex below can be matched
\S* match any non-white space character [^\r\n\t\f ]
Quantifier: Between zero and unlimited times, as many times as possible, giving back as needed [greedy]
[A-Z] match a single character present in the list below
A-Z a single character in the range between A and Z (case sensitive)
(?=\S*[\d]) Positive Lookahead - Assert that the regex below can be matched
\S* match any non-white space character [^\r\n\t\f ]
Quantifier: Between zero and unlimited times, as many times as possible, giving back as needed [greedy]
[\d] match a single character present in the list below
\d match a digit [0-9]
(?=\S*[\W]) Positive Lookahead - Assert that the regex below can be matched
\S* match any non-white space character [^\r\n\t\f ]
Quantifier: Between zero and unlimited times, as many times as possible, giving back as needed [greedy]
[\W] match a single character present in the list below
\W match any non-word character [^a-zA-Z0-9_]
\S* match any non-white space character [^\r\n\t\f ]
Quantifier: Between zero and unlimited times, as many times as possible, giving back as needed [greedy]
$ assert position at end of the string
To be quite honest your regex is so far off from the tutorial you've
linked that it's not even remotely close. I would recommend you go
back and thoroughly re-read and study the guide, for it's apparent you
haven't applied any of it to be applicable by any means.

How Match Regular expression of international number in android

i have a EditText in my activity where i take a phone number from user.. Now user provides a number activity and based on xml rules you i have to tell whether application routes the phone number or not.
This is more of a java question, you need to know how to build regular expressions. So I assume you know how to fetch the value of the edit text. Lets assume you have loaded the phone number in a String phoneNumber. So now how do you check against a regular expression:
import java.util.regex.Pattern;
import java.util.regex.Matcher;
....
Pattern pattern = Pattern.compile("\+0[8-9][0-9]{2}-[0-9]{2}-[0-9]{3}");
Matcher matcher = pattern.matcher(phoneNumber);
if (matcher.matches()) {
// The phone number matches the template given. do the routing.
}
In th eexample I have given I am searching for phone numbers that start with + (note that + is a special character for regexes, thus I need to escape it, the same holds for $, ., ^), then I expect a zero, 8 or 9, then exactly 2 digits, a dash 2 more digits and 3 more digits. The if matcher.matches() will return true only if the phoneNumber is exactly of the described format. Hopefully this will give you a brief introduction to the regex power of java.
ITU: National Numbering Plans can help you with the harder problem.
Your question is poor enough that any one of my link, Boris's regex-centric answer, or an answer that focused on nothing more than Android's GUI could be what you're really looking for. Please keep this in mind for future questions.

Categories

Resources