check if an input string is of a specific pattern - java

How do I check if the user inputs a String in a particular pattern. I want the user to input a number, then a comma, followed by a number again. For example, 3,3 or 4,4. If the user enters for eg: 3,,3 it should not be accepted.

Use regex \d+ match numbers groups:
String input = "3,3";
System.out.println(input.matches("\\d+,\\d+")); // should be true
update:
If more than two numbers are allowed, use (\\d+,)+\\d+ to match multiple groups.

You can use regex for this task. The correct pattern would be ^(\\d+,)+\\d+$.
String[] str = {
"3,3",
"2,3,3",
"2,2,,"
};
for(String s : str) {
if( s.matches("(\\d+,)+\\d+$") ) {
System.out.printf("%s matched%n", s);
}
}
Breakdown:
^ asserts position at start of a line
1st Capturing Group (\d+,)+
+ Quantifier — Matches between one and unlimited times, as many times as possible, giving back as needed (greedy)
\d+ matches a digit (equal to [0-9])
, matches the character , literally (case sensitive)
\d+ matches a digit (equal to [0-9])
+ Quantifier — Matches between one and unlimited times, as many times as possible, giving back as needed (greedy)
$ asserts position at the end of a line

First, take a look at RegExr and try it some stuff there.
For your question, use the next pattern: \d+,\d+

Since the question labeled with Scanner I assume that you want to use it, so you can do it this way
Scanner sc = new Scanner(System.in);
if (sc.hasNext("\\d+,\\d+")) {
// code for good case
} else {
// not matched
}
Hope it helps!

Try the following:
public class Demo3 extends AppCompatActivity {
private EditText edt;
private Button b;
private TextView tv;
private String days;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.demo3);
edt = (EditText) findViewById(R.id.edt);
tv = (TextView) findViewById(R.id.tv);
b = (Button) findViewById(R.id.b);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(!edt.getText().toString().isEmpty()) {
String[] split_space = edt.getText().toString().split(",");// TODO: Check if input is actually an Integer , Integer.
if (split_space.length == 2) {
if(isValidInteger(split_space[0]) && isValidInteger(split_space[1])){
tv.setText("accepted");
}else{
tv.setText("not accepted (contains characters)");
}
} else {
tv.setText("not accepted (doesn't respect format (3,3 or 4,4 or ...))");
}
}else {
tv.setText("not accepted (empty)");
}
}
});
}
private boolean isValidInteger(String value) {
if (value == null) {
return false;
} else {
try {
Integer val = Integer.valueOf(value);
if (val != null)
return true;
else
return false;
} catch (NumberFormatException e) {
return false;
}
}
}
}
demo3.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/edt"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="null"
android:id="#+id/tv"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Check"
android:layout_marginTop="50dp"
android:id="#+id/b"/>
</LinearLayout>

Scanner scan = new Scanner(System.in);
String str= null;
if(scan.hasNext("\\d+,\\d+")){
str = scan.next();
}
if(str != null){
System.out.println("Valid User Input: {"+str+"} Recieved");
}
else{
System.out.println("Invalid User Input");
}
str would be equal to null if the pattern doesnot match

Related

Programming issue at work place related to string

I have a string which is searched based on the delimiter " (double quote).
So when I enter the string "program", it is able to search the beginning and end of the string based on the delimiter and returns me the string program which I put in a vector.
Now, if I enter a string "program"123"" it returns me substrings like program, 123, 123".
Now the result I want is program"123" which is a valid string as per the usecase but it contains " as part of the string and this is where the search by delimiter fails to distinguish between the beginning and end of the string.
Can someone help with some logic?
The following is the method I am using.
enter code here
public static PVector tokenizeInput(final String sCmd)
throws ExceptionOpenQuotedString
{
if (sCmd == null)
{
return null;
}
PVector rc = new PVector();
if (sCmd.length() == 0)
{
rc.add(StringTable.STRING_EMPTY);
return rc;
}
char chCurrent = '\0';
boolean bInWhitespace = true;
boolean bInQuotedToken = false;
boolean bDelim;
int start = 0;
int nLength = sCmd.length();
for (int i = 0; i < nLength; i++)
{
chCurrent = sCmd.charAt(i); // "abcd "ef"" rtns abdc ef ef"
bDelim = -1 != APIParseConstants.CMD_LINE_DELIMS.indexOf(chCurrent);
if (bInWhitespace) // true
{
// In whitespace
if (bDelim)
{
if ('\"' == chCurrent)
{
start = i + 1;
bInQuotedToken = true;
bInWhitespace = false;
} // if ('\"' == chCurrent)
}
else
{
start = i;
bInWhitespace = false;
} // else - if (bDelim)
}
else
{
// Not in whitespace
boolean bAtEnd = i + 1 == nLength;
if (!bDelim)
{
continue;
}
else
{
if ('\"' == chCurrent)
{
if (!bInQuotedToken)
{
// ending current token due to '"'
if (bAtEnd)
{
// non terminated quoted string at end...
throw new ExceptionOpenQuotedString(
sCmd.substring(start));
}
else
{
rc.add(sCmd.substring(start, i)); // include quote
bInQuotedToken = true;
bInWhitespace = false;
} // if (bAtEnd)
}
else
{
// ending quoted string
//if (!bAtEnd)
{
rc.add(sCmd.substring(start, i)); // don't include quote
bInQuotedToken = false;
bInWhitespace = true;
} // if (bAtEnd)
} // else - if (!bInQuotedToken)
}
else
{
// got delim (not '"')
if (!bAtEnd && !bInQuotedToken)
{
rc.add(sCmd.substring(start, i));
bInWhitespace = true;
} // if (bAtEnd)
} // else - if ('\"' == chCurrent)
} // else - if (!bDelim)
} // else - if (bInWhitespace)
} // for (short i = 0; i < nLength; i++)
if (!bInWhitespace && start < nLength)
{
if (!bInQuotedToken || chCurrent == '"')
{
rc.add(sCmd.substring(start));
}
else
{
throw new ExceptionOpenQuotedString(sCmd.substring(start));
} // else - if (!bInQuotedToken)
} // if (!bInWhitespace && start < nLength)
return rc;
}
You should escape the internal ".
Otherwise, you could check for the position of the first and last " characters and split/cut the string using those positions as delimiters.
Whenever you embed one encoding (all possible strings) inside another (quoted strings) there are only a few basic techniques to allow you to parse them unambiguously:
Disallow certain inputs. For instance, don't allow quote characters. Now you know they are always delimiters. In your case, you could choose a new delimiter besides quote and disallow that in your input. This is rarely desirable, because you often end up wanting to allow the input you previously thought you didn't need.
Include the length of the input in the encoding. For example, instead of quotes you could precede each string with the number of characters in it.
Escaping. Some inputs cannot be represented directly. Instead, at least one character is reserved as the escape character. It indicates that whatever follows it should be interpreted in a different way. In Java strings, the backslash is the escape character. If you only need the escape character for a single reason, you may want to follow the example of some SQL dialects and double it. In SQL, a quote is the quote character for strings, so to include a literal quote character in a string, you type two quotes.

Android: How do I check if the equation is right and shows error message instead of crashing?

I'm trying to create a calculator which is successful in calculating numbers but the problem is it crashes whenever I enter a wrong equation. I need your help on how to prevent the users to enter wrong equations.Examples of wrong equations
*1*1, 1**2, 2+++2, 2+2+, etc
Below is the block of codes from MainActivity.java I need you guys to help me improve this one
public void onClick(View v) {
String stringEq = equation.getText().toString();
switch(v.getId()) {
case R.id.equals:
String[] digits = stringEq.split("[0-9]+");
String[] spChar = stringEq.split("[-+*/]");
int result = Integer.parseInt(spChar[0]);
for(int i=1; i<spChar.length; i++){
if(digits[i].equals("+"))
result += Integer.parseInt(spChar[i]);
else if (digits[i].equals("-"))
result -= Integer.parseInt(spChar[i]);
else if (digits[i].equals("*"))
result *= Integer.parseInt(spChar[i]);
else if (digits[i].equals("/"))
result /= Integer.parseInt(spChar[i]);
else
result = 0;
}
ans.setText(String.valueOf(result));
break;
case R.id.sim:
Intent act = new Intent(Main2Activity.this, MainActivity.class);
startActivity(act);
break;
}
}
I'll also add the EditText from the xml file maybe some of you need to see it
<EditText
android:id="#+id/equation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="phone"
android:digits="0123456789+-*/"
android:maxLength="12"
android:hint="Enter equation"/>
Thanks in advance
I've seen your first question : To Avoid Type Operator for Twice
Maybe you should use onTextChangeListener to judge user's input
Here is my code.
final EditText editText = (EditText) findViewById(R.id.text);
editText.addTextChangedListener(new TextWatcher() {
boolean ignore = false;
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
private boolean shouldIgnore(char input) {
return !(input >= '0' && input <= '9');
}
#Override
public void afterTextChanged(Editable s) {
int idx_of_last = s.length() - 1;
if (!ignore && idx_of_last >= 0) {
char last = s.charAt(idx_of_last);
if (shouldIgnore(last)) {
if (s.length() == 1 || (s.length() > 1 && shouldIgnore(s.charAt(idx_of_last - 1)))) {
ignore = true;
s.delete(idx_of_last, idx_of_last + 1); // after this , onTextChanged will be called
ignore = false;
} else {
Log.d("KEY_CHANGE", "Format Right");
}
} else {
Log.d("KEY_CHANGE", "Last Is Number");
}
}
}
});
You can follow TDD (test driven development). This means write the test cases first and then write the code. You can unit testing frameworks for this.
Initially, it will take time but you will get your equation right. Also, try to use debugging mode and just stop the debugger before you are getting a crash.
This way you can debug at run time and change the equation.
Before using String stringEq for calculation, you should add your validation method to validate stringEq, Such as no two consecutive operators and no operator at the end

Working solution to check String for only integer numbers? [duplicate]

This question already has an answer here:
Java String - See if a string contains only numbers and not letters
12 answers
I know this question was posted a lot and I checked some solutions but none were working perfectly for me.
What I want is to check whether a Stringinput in a TextField is valid or not. Valid entries are only positive integers, in other words everything that is >=0 and an integer.
I tried a solution something like this that I found:
try {
int input = Integer.valueOf(fieldwaitAfterAction.getText());
if(input < 0)) {
validInput = false;
} else {
validInput = true;
}
} catch(NumberFormatException e) {
validInput = false;
}
Works for most of the wrong patterns fine, but if I enter something like '+0' or '-0' it passes through which shouldn't be actually the case.
So I want a pure integer number without any characters at the beginning, in between or at the end.
What would the best solution be for this problem?
Thanks a lot!
public static boolean checkForDigits(final String toCheck){
boolean flag = true;
char[] toCheckArray = toCheck.toCharArray();
for(int index=0; index < toCheckArray.length, flag==true; index++){
if( ! ( ( (int)toCheckArray[index] > 47 ) && ( (int)toCheckArray[index] < 58 ) ) ){
flag = false;
}
}
return flag;
}
There you go. It returns true if all are digits, false if it does not.
It is O(n) time worst case. < O(n) if it detects anything other than a digit.
I think you forgot to put = to.If i understood your question correctly this should fix your problem:
try{
String input_string=fieldwaitAfterAction.getText()
int input = Integer.valueOf(input_string);
if(input <= 0)){
validInput = false;
}
else{ validInput = true; }
}
catch(NumberFormatException e){
validInput = false;
}
You can use Regex ^\d+$ to check if a input contains only positive number.
^ assert position at start of the string
\d+ match a digit [0-9]
Quantifier: + Between one and unlimited times, as many times as possible, giving back as needed [greedy]
$ assert position at end of the string
In Java code:
String[] arr = { "-123", "123a", "0", "123" };
String regex = "^\\d+$";
for (String str : arr) {
Matcher matcher = Pattern.compile(regex).matcher(str);
if (matcher.find())
System.out.println("String " + str + " is a positive number.");
else
System.out.println("String " + str + " is NOT a positive number.");
}
prints
String -123 is NOT a positive number.
String 123a is NOT a positive number.
String 0 is a positive number.
String 123 is a positive number.
For me, this always do the magic....
try {
Integer.parseInt(theStringToEval);
// is this line is reach.. it is a int
}
catch (NumberFormatException e){
// is the flow goes here
}
But it allows integer with signs... You could create a method for your convenience that hide this implementation details and add the check for the signs in there...
public static boolean isPlainInteger (String string) {
if (string.startsWith("-") || string.startsWith("+")) {
return false;
}
try {
Integer.parseInt(string);
return true;
}
catch (NumberFormatException e){
return false;
}
}
And you can achieve it through regex too.... perhaps this one could help.
private static Pattern plainIntegerPattern = Pattern.compile("\\d+");
public static boolean isPlainInteger (String string) {
return plainIntegerPattern.matcher(string).matches();
}
Hope it helps.
Integer.ValueOf allows + ans - signs. As per javadoc
...The characters in the string must all be digits of the specified radix (as determined by whether java.lang.Character.digit(char, int) returns a nonnegative value), except that the first character may be an ASCII minus sign '-' to indicate a negative value or an ASCII plus sign '+' to indicate a positive value
So Your code will break for any value having + followed by an integer and also +0 and -0 as both of them will result as 0. I'll give solution using regex.
String str = fieldwaitAfterAction.getText();
if (str == null) {
retrun false;
}
String regex = "^(\\d+)$";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(str);
if (matcher.matches()) {
int val = Integer.valueOf(matcher.group(0));
if (val > 0) {
return true;
}
}
retrun false;
This way you could handle situation like 088 not being a valid input to you by using reges ^[^0](\\d+)$.
Checks if the given input is a integer number, not a valid Java Integer (Integer.MAX_VALUE).
validInput = fieldwaitAfterAction.getText().length > 0
&& fieldwaitAfterAction.getText().matches("[0-9]+");
You can use a simple regexp, like "(^0|[1-9]*\d)$". This allows you to put 0 or any positive integer.
fieldwaitAfterAction.getText().matches("(^0|[1-9]*\\d)$")
Remember that using regexp like \d+ won't work, because it will accept strings like "001243"

Float and Integer numbers EditText

Hi I am trying to do an EditText that only accepts float or integer numbers. I am doing like that but not works fine:
myedit=(EditText)findViewById(R.id.my_edit);
myedit.setInputType(InputType.TYPE_NUMBER_FLAG_DECIMAL);
I have also write like that:
if(!myedit.getText().toString().matches("[a-zA-Z? ]*"){
//do something
}
else{
//no correct values
}
Can somebody help me?
You have to set input filter to the edit text...
et.setFilters(new InputFilter[] {
new DigitsKeyListener(Boolean.FALSE, Boolean.TRUE) {
int beforeDecimal = 5, afterDecimal = 2;
#Override
public CharSequence filter(CharSequence source, int start, int end,
Spanned dest, int dstart, int dend) {
String temp = et.getText() + source.toString();
if (temp.equals(".")) {
return "0.";
}
else if (temp.toString().indexOf(".") == -1) {
// no decimal point placed yet
if (temp.length() > beforeDecimal) {
return "";
}
} else {
temp = temp.substring(temp.indexOf(".") + 1);
if (temp.length() > afterDecimal) {
return "";
}
}
return super.filter(source, start, end, dest, dstart, dend);
}
}
});
Could you please try with
android:input = "number" in your xml file.
This will set your edit text to get numbers only as input
The easiest way to do this is to just set the digits attribute to accept only valid integer and decimal values:
android:digits="0123456789."
Although you probably still should wrap the conversion in a try/catch for NumberFormatException just in case there's some edge entry case I'm not aware of.
Sorry this is late, but possibly it may help someone else stuck with this.
The easiest way I have found to accomplish this is to set the android:input value like so:
<EditText
android:id="#+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="numberDecimal|numberSigned" />
"numberDecimal" - means that it will accept floating point numbers.
"numberSigned" - means it will accept positive & negative numbers.
This ^^^ combination will only allow users to enter integers or floating point numbers!
Then if you wish to parse this value you may want to try something like this:
String numberAsString = "22.13";
try {
int number = Integer.parseInt(numberAsString);
} catch (NumberFormatException e) {
try {
float number = Float.parseFloat(numberAsString);
} catch (NumberFormatException ex) {
Log.e(TAG, "Not float value", e);
Log.e(TAG, "Not integer value", ex);
}
}

StringTokenizer issues with if statements

I have to tokenize a string which looks like this:
4830673048;Tony White
There must be two tokens separated by a ;
The first token must contain 10 digits, and ONLY digits
The second token may not contain digits.
private static boolean isValid(String accountLine) throws BankAccountException
{
StringTokenizer strTok = new StringTokenizer(accountLine, ";");
boolean valid = true;
if(strTok.countTokens() == 2)
{
if(strTok.nextToken().length() == 10 && strTok.nextToken().matches(".*[0-9].*"))
{
if(!strTok.nextToken().matches(".*[0-9].*"))
{
valid = true;
}
}
}
else
{
System.out.println("Invalid Bank Account info. " + strTok.nextToken());
valid = false;
}
return valid;
}
Here is the code I came up with, but it doesn't do what I expected it to do. I know the problem probably lies in my use of .nextToken(). So then my question is, what's the proper StringTokenizer method for ONLY checking the first or the second token?
See if this works for you:
private static boolean isValid(String accountLine) throws BankAccountException
{
StringTokenizer strTok = new StringTokenizer(accountLine, ";");
boolean valid = true;
if(strTok.countTokens() == 2)
{
String acctNum = strTok.nextToken();
String acctHolder = strTok.nextToken();
if(acctNum.length() == 10
&& acctNum.matches(".*[0-9].*")
&& !acctHolder.matches(".*[0-9].*"))
{
valid = true;
}
}
else
{
System.out.println("Invalid Bank Account info. " + strTok.nextToken());
valid = false;
}
return valid;
}
In the code you posted, you were calling nextToken two times while evaluating the first token, inadvertently moving on to the second token too soon. By assigning the values to variables first, you can easily eliminate this issue.
Just use String.matches() with the appropriate regex and you only need one line:
return accountLine.matches("\\d{10};[^\\d]+");
Unless this is used in more than place, I would just scrap the method and use the snippet in-line.
if(strTok.nextToken().length() == 10 && strTok.nextToken().matches(".*[0-9].*"))
{
if(!strTok.nextToken().matches(".*[0-9].*"))
{
valid = true;
}
}
Now let's look at this code. You first say strTok.nextToken().matches(".*[0-9].*") and than say !strTok.nextToken().matches(".*[0-9].*"). Just delete the inner if and try. You don't need a regex match for second token, so no action is needed for that.
I did some research and found this solid example from Mkyong whose tutorials I admire. In the tutorial he wrote:
while (st.hasMoreElements()) {
System.out.println(st.nextElement());
}
Instead of directly using nextToken().
This tutorial of Oracle gives more decent and all-around explanation. In that, nextToken() is deeply explained and exampled.
As you'll see in both examples, nextToken() and nextElement() functions both take the next token from the tokenizer. So you'll need to assign the first call of one of these functions to a variable and do controls on that. Such as:
String firstToken = st.nextToken().toString();
if(firstToken .length() == 10 && firstToken .matches(".*[0-9].*")) {
...
}
Don't forget to use toString() after nextToken().
Try this:
private static boolean isValid(String accountLine) throws BankAccountException
{
StringTokenizer strTok = new StringTokenizer(accountLine, ";");
boolean valid = true;
String bankAccount = (String)strTok.nextElement();
if(strTok.countTokens() == 2)
{
if(strTok.nextToken().length() == 10 && bankAccount.matches(".*[0-9].*"))
{
valid = true;
}
}
else
{
System.out.println("Invalid Bank Account info. " + bankAccount);
valid = false;
}
return valid;
}

Resources