-3

Edit: I solving the following task, but I have some problems with it.

Task: Write a program that selects a correctly formatted phone number from the text and, if it matches a regular expression, lists the entire match with the regular expression separately, the country code separately, and the phone number separately. The corrects formats are: +xxx xxx xxx xxx, (xxx) xxx xxx xxx, xxx xxx xxx, xxxxxxxxx, +xxxxxxxxxxxx. I need this task #C .NET 4.7.2. Thanks for help.

I have this code:

using System.Linq;
using System.Text.RegularExpressions;
                    
public class Program {
  private static string MakeRegex(params string[] patterns) {
    string SinglePattern(string pattern) => "(?:^" + string.Concat(Regex
      .Split(pattern, "(x+)")
      .Select(item => item.StartsWith('x')
         ? $"[0-9]{{{item.Length}}}"
         : string.Concat(item.Select(c => Regex.Escape(c.ToString()))))) + "$)";

     return string.Join("|", patterns.Select(pattern => SinglePattern(pattern))); 
  }
    
  public static void Main() {
    string Patterns = MakeRegex(
      "+xxx xxx xxx xxx",
      "(xxx) xxx xxx xxx",
      "xxx xxx xxx",
      "xxxxxxxxx",
      "+xxxxxxxxxxxx"
    );

    string[] PhoneNumbers = new string[] {
      "+420 000 111 222",
      "(420) 000 111 222",
      "111 000 222",
      "000111222",
      "+420000111222",
      "000111",
      "+(420) 000 111 222"
    };  
    
    string numbers = string.Join(Environment.NewLine, PhoneNumbers
      .Select(test => $"{test,20} : {(Regex.IsMatch(test, Patterns) ? "Matched" : "No")}"));
      
    string[] ns = numbers.Split('\n');
    foreach (var n in ns)
    {
        Console.WriteLine(n);       
    }
  }
}
  • you can check out the answers to the same question here https://stackoverflow.com/questions/18091324/regex-to-match-all-us-phone-number-formats – Hassan Liasu Oct 30 '21 at 12:35

1 Answers1

1

Having a collection of patterns like

+xxx xxx xxx xxx, 
(xxx) xxx xxx xxx, 
xxx xxx xxx, 
xxxxxxxxx, 
+xxxxxxxxxxxx

We can combine them into a single regular expression with a help of regular expressions and Linq:

using System.Linq;
using System.Text.RegularExpressions;

...

private static string MakeRegex(params string[] patterns) {
  static string SinglePattern(string pattern) => "(?:^" + string.Concat(Regex
    .Split(pattern, "(x+)")
    .Select(item => item.StartsWith('x')
       ? $"[0-9]{{{item.Length}}}"
       : string.Concat(item.Select(c => Regex.Escape(c.ToString()))))) + "$)";

  return string.Join("|", patterns.Select(pattern => SinglePattern(pattern))); 
}

Usage

string phonePattern = MakeRegex(
  // Add / Edit / Remove patterns, if required  
  "+xxx xxx xxx xxx", 
  "(xxx) xxx xxx xxx", 
  "xxx xxx xxx", 
  "xxxxxxxxx", 
  "+xxxxxxxxxxxx"
);

...

if (Regex.IsMatch(pnumber, phonePattern)) {
  ...
}

Demo:

  string phonePattern = MakeRegex(
    "+xxx xxx xxx xxx",
    "(xxx) xxx xxx xxx",
    "xxx xxx xxx",
    "xxxxxxxxx",
    "+xxxxxxxxxxxx"
  );

  string[] tests = new string[] {
    //TODO: Add more tests here
    "+123 456 789 777",
    "(123) 456 789 444",
    "123 456 789",
    "123456789",
    "+123456789567",

    "12345678",
    "1234567899",
    "1234 56 789",

    "123456789",   // Expected "Matched" (see comments below)    
    "670 230 465", // Expected "Matched" (see comments below)
    "2736896",     // Expected "No" (see comments below)
    "593683",      // Expected "No" (see comments below)
  };

  string report = string.Join(Environment.NewLine, tests
    .Select(test => $"{test,20} : {(Regex.IsMatch(test, phonePattern) ? "Matched" : "No")}"));

  Console.Write(report);

Outcome:

  +123 456 789 777 : Matched
 (123) 456 789 444 : Matched
       123 456 789 : Matched
         123456789 : Matched
     +123456789567 : Matched
          12345678 : No
        1234567899 : No
       1234 56 789 : No
         123456789 : Matched
       670 230 465 : Matched
           2736896 : No
            593683 : No

Please, fiddle yourself

Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
  • So it should look like that, am I right? using System; using System.Text.RegularExpressions; static void Main() { string pnumber = "123456789"; string phonePattern = MakeRegex("+xxx xxx xxx xxx", "(xxx) xxx xxx xxx", "xxx xxx xxx", "xxxxxxxxx", "+xxxxxxxxxxxx" ); if (Regex.IsMatch(pnumber, phonePattern)) { Console.WriteLine("Correct"); } } } –  Oct 30 '21 at 13:52
  • @Alb43: yes, somerthing like this. Instead of implementing `phonePattern` *manually* we can build it with a help of `MakeRegex` – Dmitry Bychenko Oct 30 '21 at 13:55
  • what is wrong in my code in previous messaging, it dnes not work. Thanks for help –  Oct 30 '21 at 19:25
  • @Alb43: could you provide *counter examples* - test cases when expected result doesn't mean actual one? – Dmitry Bychenko Oct 30 '21 at 19:51
  • https://dotnetfiddle.net/siOj5W to play with the code – Dmitry Bychenko Oct 30 '21 at 19:57
  • Yes, here are some examples. 1) 123456789 - will pass, it is correct phone number 2) 670 230 465 - it will also pass 3) 2736896 - this won't pass, it is not correct format 4) 593683" - it also won't pass, it is not correct. –  Oct 30 '21 at 19:59
  • @Alb43: I've put your examples (see my edit) and they've been processed as expected: first two matched, last two failed to match. I've asked you about *counter examples*: test cases when *actual* result doesn't meet expected one: say, when you want *Matched* but my code returns *Not* and vice versa – Dmitry Bychenko Oct 30 '21 at 20:07
  • Thank you so much for your help, I have played and tried a lot with the code, but need help with the final step - I need to complete (the edited) task. Thanks for your help. –  Oct 31 '21 at 20:53
  • @Alb43: if you want to match phones somewhere *within* th text, you should remove `^` and `$` from `MakeRegex`. I've added parsed demo into https://dotnetfiddle.net/siOj5W – Dmitry Bychenko Oct 31 '21 at 21:55