Xelian
Xelian

Reputation: 17208

Search phone number with regex Java

I want to find numbers like

(123).234.4567
(123)-234-4567
123.234.4567
123-456-4567

This digits represents US phone numbers. So they can be separated with -(dash) or .(dot) and must have 3 digits, followed by another 3 digits, followed by 4 more. And the first 3 digits can be fenced or not with brackets '()'.

and code is like below

 Pattern regex = Pattern.compile("^(\\(\\d{3}\\))|^\\d{3}[.-]?\\d{3}[.-]?\\d{4}$");
 Matcher matcher = regex.matcher("(425).882.8080 tel");
 while(matcher.find()){
        System.out.println(matcher.group());
}

But the result is :

(425)

What I am doing Wrong. I want to print (425).882.8080 at once.

Upvotes: 0

Views: 844

Answers (3)

Braj
Braj

Reputation: 46841

You can try Back reference to check for exact match.

Backreferences match the same text as previously matched by a capturing group

          ^(\(\d{3}\)|\d{3})([.-])\d{3}\2\d{4}$
Capture 2nd group -----------^^^^      ^^-------- Same text as 2nd captured group

Groups are captured by enclosing it inside the parenthesis (...) and can be accessed by \index

Here is online demo

Note: If you want to find substring in a string then remove ^ and $ that are used for beginning and ending of the string respectively.

Patten explanation:

  (                        group and capture to \1:
    \(                       '('
    \d{3}                    digits (0-9) (3 times)
    \)                       ')'
   |                        OR
    \d{3}                    digits (0-9) (3 times)
  )                        end of \1

  (                        group and capture to \2:
    [.-]                     any character of: '.', '-'
  )                        end of \2

  \d{3}                    digits (0-9) (3 times)
  \2                       what was matched by capture \2
  \d{4}                    digits (0-9) (4 times)

Sample code:

String regex="(\\(\\d{3}\\)|\\d{3})([.-])\\d{3}\\2\\d{4}";

System.out.println("(123).234.4567".matches(regex)); // true
System.out.println("(123)-234-4567".matches(regex)); // true
System.out.println("123.234.4567".matches(regex));   // true
System.out.println("123-456-4567".matches(regex));   // true

System.out.println("(123)-234.4567".matches(regex)); // false
System.out.println("(123-234-4567".matches(regex));  // false
System.out.println("123.234-4567".matches(regex));   // false
System.out.println("123-456.4567".matches(regex));   // false

Sample code: (as per your's)

Matcher matcher = Pattern.compile(regex).matcher("(425).882.8080 tel");
while (matcher.find()) {
    String str = matcher.group();
    System.out.println(str);  // (425).882.8080
}

Upvotes: 1

Avinash Raj
Avinash Raj

Reputation: 174696

You don't need to put start and end anchors in your regex if the phone number would appears anywhere on the input.

\d{3}([.-])?\d{3}\1?\d{4}|\(\d{3}\)([.-])?\d{3}\2?\d{4}

DEMO

Java regex would be,

"\\d{3}([.-])?\\d{3}\\1?\\d{4}|\\(\\d{3}\\)([.-])?\\d{3}\\2?\\d{4}"

Example:

Pattern regex = Pattern.compile("\\d{3}([.-])?\\d{3}\\1?\\d{4}|\\(\\d{3}\\)([.-])?\\d{3}\\2?\\d{4}");
 Matcher matcher = regex.matcher("(425).882.8080 tel");
 while(matcher.find()){
        System.out.println(matcher.group());
} // (425).882.8080

Upvotes: 0

MrTux
MrTux

Reputation: 33993

You only have one matching group: (\\(\\d{3}\\))

Try

 Pattern.compile("^((?:\\(\\d{3}\\))|^\\d{3}[.-]?\\d{3}[.-]?\\d{4})");

this will provide you the whole matched number.

If you, instead, need all numbers separately you have to add multiple matching groups, like

     Pattern.compile("^(\\(\\d{3}\\))|^(\\d{3})[.-]?(\\d{3})[.-]?(\\d{4})");

Btw. by using [.-]? you will also match 1232344567 (without dots/dashes). To fix this, drop the ? after [.-].

An optimized version could be:

Pattern.compile("^((\\((\\d{3})\\)|(\\d{3}))[.-](\\d{3})[.-](\\d{4}))");

This way you get the whole matched number as well as all included nubmers separately.

Another point: your ininital regexp would also match 123.234-4567 If that's not desireable, anothe OR is needed for all cases.

E.g.

Pattern.compile("^((\\((\\d{3})\\)|((\\d{3})\\.(\\d{3})\\.(\\d{4})|(\\d{3})-(\\d{3})-(\\d{4})))");

Updated for you last edit:

Pattern.compile("^((?:\\(\\d{3}\\)|\\d{3})(?:\\.\\d{3}\\.\\d{4}|\\d{3}-\\d{3}-\\d{4}))");

Upvotes: 1

Related Questions