1

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));
Zabuzard
  • 25,064
  • 8
  • 58
  • 82
ziyu zhang
  • 41
  • 4
  • 2
    You should generally ask one question at a time. Here you've clearly got two very independent questions. I suggest you [edit] it. – Sweeper Apr 15 '18 at 14:29

2 Answers2

0

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.

Zabuzard
  • 25,064
  • 8
  • 58
  • 82
  • I don't understand why you suggested the pattern `[a-Z-a-z]+`. Can you explain this? And I also don't understand `(\\$+)(\\d)`. Why would a currency have more than one dollar sign? – Tim Biegeleisen Apr 15 '18 at 14:37
  • @TimBiegeleisen That was a typo, corrected. Let me know if anything is unclear. The dollar-thing was used like this by OP, removed it too. – Zabuzard Apr 15 '18 at 14:38
  • "\\$\\d+" I use this, but it doesn't work. The output is null, like this "[ ]". – ziyu zhang Apr 16 '18 at 02:44
  • btw, I need to input a string. For example, '$22 $23 $24 25', and output should be like this [$22, $23, $24]. Please tell me how to program this. T_T – ziyu zhang Apr 16 '18 at 02:54
  • @ziyuzhang I would suggest to ask a new question. StackOverflow is not meant for "discussion". Of course you can link to this question if the new one is related. – Zabuzard Apr 16 '18 at 11:19
0

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.

Tim Biegeleisen
  • 502,043
  • 27
  • 286
  • 360