How do I specify input from a user? - java

I'm writing a program and I would like to call for a specially-formed string that consists of 3 letters (can be upper-case or lower-case), followed by a dash and then followed by 4 numbers.
For example, "abc-1234".
The value must follow this pattern, otherwise, they are invalid.

You can use String regex with String's match method:
String pattern = "[\\w^\\d]{3}-\\d{4}";
This is a template for 'ccc-dddd', where d is a number from [0-9] and c is a word character, not including [0-9].
Then, you can see if your input string matches the template:
if(input.matches(pattern)) { //input is input string
...
} else {
System.out.println("Input does not match template ccc-dddd");
}

Related

Replace multiple non-digit char to 1 non-digit char

I am working on app that read weight value from weighing indicator. The output from the indicator are contains with symbols, non digit char and also a number. I just want to extract the number. I have already turn non-digits and symbols into several pipes using regex \D. Then I wanted to turn this string
||||||||||1234||||||||||||||1234||||||||||||||1234||||||||||||||1234||||||||||||||1234||||
into
|1234|1234|1234|1234
How could I possibly do that?
You could try a regex replacement:
String input = "||||||||||1234||||||||||||||1234||||||||||||||1234||||||||||||||1234||||||||||||||1234||||";
String output = input.replaceAll("\\|+", "|").replaceAll("\\|$", "");
System.out.println(output); // |1234|1234|1234|1234|1234

Why does this regex fails to check accurately?

I have the following regex method which does the matches in 3 stages for a given string. But for some reason the Regex fails to check some of the things. As per whatever knowledge I have gained by working they seem to be correct. Can someone please correct me what am I doing wrong here?
I have the following code:
public class App {
public static void main(String[] args) {
String identifier = "urn:abc:de:xyz:234567.1890123";
if (identifier.matches("^urn:abc:de:xyz:.*")) {
System.out.println("Match ONE");
if (identifier.matches("^urn:abc:de:xyz:[0-9]{6,12}.[0-9]{1,7}.*")) {
System.out.println("Match TWO");
if (identifier.matches("^urn:abc:de:xyz:[0-9]{6,12}.[a-zA-Z0-9.-_]{1,20}$")) {
System.out.println("Match Three");
}
}
}
}
}
Ideally, this code should generate the output
Match ONE
Match TWO
Match Three
Only when the identifier = "urn:abc:de:xyz:234567.1890123.abd12" but it provides the same output event if the identifier does not match the regex such as for the following inputs:
"urn:abc:de:xyz:234567.1890123"
"urn:abc:de:xyz:234567.1890ANC"
"urn:abc:de:xyz:234567.1890123"
"urn:abc:de:xyz:234567.1890ACB.123"
I am not understanding why is it allowing the Alphanumeric characters after the . and also it does not care about the characters after the second ..
I would like my Regex to check that the string has the following format:
String starts with urn:abc:de:xyz:
Then it has the numbers [0-9] which range from 6 to 12 (234567).
Then it has the decimal point .
Then it has the numbers [0-9] which range from 1 to 7 (1890123)
Then it has the decimal point ..
Finally it has the alphanumeric character and spcial character which range from 1 to 20 (ABC123.-_12).
This is an valid string for my regex: urn:abc:de:xyz:234567.1890123.ABC123.-_12
This is an invalid string for my regex as it misses the elements from point 6:
urn:abc:de:xyz:234567.1890123
This is also an invalid string for my regex as it misses the elements from point 4 (it has ABC instead of decimal numbers).
urn:abc:de:xyz:234567.1890ABC.ABC123.-_12
This part of the regex:
[0-9]{6,12}.[0-9]{1,7} matches 6 to 12 digits followed by any character followed by 1 to 7 digits
To match a dot, it needs to be escaped. Try this:
^urn:abc:de:xyz:[0-9]{6,12}\.[0-9]{1,7}\.[a-zA-Z0-9\-_]{1,20}$
This will match with any number of dot alphanum at the end of the string as your examples:
^urn:abc:de:xyz:\d{6,12}\.\d{1,7}(?:\.[\w-]{1,20})+$
Demo & explanation

How to use Pattern and Matcher? [duplicate]

This question already has answers here:
Java regular expressions and dollar sign
(5 answers)
Closed 4 years ago.
I have two simple questions about Pattern.
First one is reading the given name(s) and surname. I need to tell whether they contain numbers or punctuation characters. If not, it's a valid name. Whatever I input, the output is
This is not a valid name.
What am I doing wrong?
Scanner input = new Scanner(System.in);
System.out.print("Enter: ");
String name = input.next();
Pattern p = Pattern.compile("[A-Za-z]");
Matcher m = p.matcher(name);
boolean n = m.matches();
if (n == true) {
System.out.println(name);
}
else {
System.out.println("This is not a valid name.");
}
The second question: I read a list of salary amounts that start with a dollar sign $ and followed by a non-negative number, and save the valid salaries into an array. My program can output an array, but it can't distinguish $.
Scanner sc = new Scanner(System.in);
System.out.print("Enter Salary: ");
String salary = sc.nextLine();
Pattern pattern = Pattern.compile("($+)(\\d)");
Matcher matcher = pattern.matcher(salary);
String[] slArray=pattern.split(salary);
System.out.print(Arrays.toString(slArray));
I wouldn't even use a formal matcher for these simple use cases. Java's String#matches() method can just as easily handle this. To check for a valid name using your rules, you could try this:
String name = input.next();
if (name.matches("[A-Za-z]+")) {
System.out.println(name);
}
else {
System.out.println("This is not a valid name.");
}
And to check salary amounts, you could use:
String salary = sc.nextLine();
if (salary.matches("\\$\\d+(?:\\.\\d+)?")) {
System.out.println("Salary is valid.");
}
A note on the second pattern \$\d+(?:\.\d+)?, we need to escape dollar sign, because it is a regex metacharacter. Also, I did not use ^ and $ anchors in any of the two patterns, because String#matches() by default applies the pattern to the entire string.
Edit:
If you have multiple currency amounts in a given line, then split by whitespace to get an array of currency strings:
String input = "$23 $24.50 $25.10";
String[] currencies = input.split("\\s+");
Then, use the above matching logic to check each entry.
Explanation
Your regex pattern is wrong. You are missing the symbol to repeat the pattern.
Currently you have [A-Za-z] which matches only one letter. You can repeat using
* - 0 to infinite repetitions
? - 0 to 1 repetitions
+ - 1 to infinite repetitions
{x, y} - x to y repetitions
So you probably wanted a pattern like [A-Za-z]+. You can use sites like regex101.com to test your regex patterns (it also explains the pattern in detail). See regex101/n6OZGp for an example of your pattern.
Here is a tutorial on the regex repetition symbols.
For the second problem you need to know that $ is a special symbol in regex. It stands for the end of a line. If you want to match the $ symbol instead you need to escape it by adding a backslash:
"\\$\\d+"
Note that you need to add two backslashes because the backslash itself has a special meaning in Java. So you first need to escape the backslash using a backslash so that the string itself contains a backslash:
\$\d+
which then is passed to the regex engine. The same if you want to match a + sign, you need to escape it.
Notes
If you just want to check a given String against a pattern you can use the String#matches method:
String name = "John";
if (name.matches("[A-Za-z]+")) {
// Do something
}
Also note that there are shorthand character classes like \w (word character) which is short for [A-Za-z0-9_].
Code like
if (n == true) { ... }
can be simplified to just
if (n) { ... }
Because n already is a boolean, you don't need to test it against true anymore.
To parse currency values you should consider using already given methods like
NumberFormat format = NumberFormat.getCurrencyInstance();
Number num = format.parse("$5.34");
See the documentation of the class for examples.

what will be the regex that allow only one special character in a string. e.g if a user enter a special character twice (##) then it will show invalid

import java.util.Scanner;
public class fahad
{
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
System.out.println("Enter your string");
String s = input.next();
if (s.matches("\\w{2,}\\.{0,1}\\w{2,}#\\D+\\.com"))
System.out.println("Valid: ");
else
System.out.println("Invalid: ");
}
}
There are at least two possible approaches. The easier one is to use negative lookahead:
if (s.matches("(?!.*##.*$).*")) {
System.out.println("Valid: ");
}
The lookahead assertion matches zero characters, but it matches successfully only if the pattern inside is not matched by whatever part of the input has not been matched by any previous part of the pattern (of which there is none in this case).
It's more instructive (and more widely applicable) to approach it constructively, however:
if (s.matches("[^#]*(#[^#]+)*#?")) {
System.out.println("Valid: ");
}
That matches an initial substring of non-# characters, followed by zero or more appearances of exactly one # followed by one or more non-# characters, optionally ending with one #. It will match any string -- including an empty one -- that does not contain two adjacent # characters.

Regex for numeric portion of Java string

I'm trying to write a Java method that will take a string as a parameter and return another string if it matches a pattern, and null otherwise. The pattern:
Starts with a number (1+ digits); then followed by
A colon (":"); then followed by
A single whitespace (" "); then followed by
Any Java string of 1+ characters
Hence, some valid string thats match this pattern:
50: hello
1: d
10938484: 394958558
And some strings that do not match this pattern:
korfed49
: e4949
6
6:
6:sdjjd4
The general skeleton of the method is this:
public String extractNumber(String toMatch) {
// If toMatch matches the pattern, extract the first number
// (everything prior to the colon).
// Else, return null.
}
Here's my best attempt so far, but I know I'm wrong:
public String extractNumber(String toMatch) {
// If toMatch matches the pattern, extract the first number
// (everything prior to the colon).
String regex = "???";
if(toMatch.matches(regex))
return toMatch.substring(0, toMatch.indexOf(":"));
// Else, return null.
return null;
}
Thanks in advance.
Your description is spot on, now it just needs to be translated to a regex:
^ # Starts
\d+ # with a number (1+ digits); then followed by
: # A colon (":"); then followed by
# A single whitespace (" "); then followed by
\w+ # Any word character, one one more times
$ # (followed by the end of input)
Giving, in a Java string:
"^\\d+: \\w+$"
You also want to capture the numbers: put parentheses around \d+, use a Matcher, and capture group 1 if there is a match:
private static final Pattern PATTERN = Pattern.compile("^(\\d+): \\w+$");
// ...
public String extractNumber(String toMatch) {
Matcher m = PATTERN.matcher(toMatch);
return m.find() ? m.group(1) : null;
}
Note: in Java, \w only matches ASCII characters and digits (this is not the case for .NET languages for instance) and it will also match an underscore. If you don't want the underscore, you can use (Java specific syntax):
[\w&&[^_]]
instead of \w for the last part of the regex, giving:
"^(\\d+): [\\w&&[^_]]+$"
Try using the following: \d+: \w+

Categories