2010-12-30 29 views
7

Tôi tự hỏi thực tiễn nào tốt nhất để phân tích cú pháp và xác thực số điện thoại di động trước khi gửi văn bản. Tôi đã có mã hoạt động, nhưng tôi muốn tìm ra cách tốt hơn để làm điều đó (như câu hỏi cuối cùng của tôi, đây là một phần của độ phân giải năm mới của tôi để viết mã chất lượng tốt hơn!).Thực hành tốt nhất để phân tích cú pháp và xác thực số điện thoại di động

Hiện tại, chúng tôi rất tha thứ khi người dùng nhập số vào biểu mẫu, họ có thể nhập các thông tin như "+44 123 4567890", "00441234567890", "", "+44 (0) 123456789", "012-345-6789" hoặc thậm chí "chưa có điện thoại".

Tuy nhiên, để gửi văn bản, định dạng phải là 44xxxxxxxxxx (chỉ dành cho điện thoại di động ở Vương quốc Anh), vì vậy chúng tôi cần phân tích cú pháp và xác thực nó trước khi chúng tôi có thể gửi. Dưới đây là mã mà tôi có bây giờ (C#, asp.net), nó sẽ là tuyệt vời nếu bất cứ ai có bất kỳ ý tưởng về cách cải thiện nó.

Cảm ơn,

Annelie

private bool IsMobileNumberValid(string mobileNumber) 
    { 
     // parse the number 
     _mobileNumber = ParsedMobileNumber(mobileNumber); 

     // check if it's the right length 
     if (_mobileNumber.Length != 12) 
     { 
      return false; 
     } 

     // check if it contains non-numeric characters 
     if(!Regex.IsMatch(_mobileNumber, @"^[-+]?[0-9]*\.?[0-9]+$")) 
     { 
      return false; 
     } 

     return true; 
    } 

    private string ParsedMobileNumber(string number) 
    { 
     number = number.Replace("+", ""); 
     number = number.Replace(".", ""); 
     number = number.Replace(" ", ""); 
     number = number.Replace("-", ""); 
     number = number.Replace("/", ""); 
     number = number.Replace("(", ""); 
     number = number.Replace(")", ""); 

     number = number.Trim(new char[] { '0' }); 

     if (!number.StartsWith("44")) 
     { 
      number = "44" + number; 
     } 

     return number; 
    } 

EDIT

Đây là những gì tôi đã kết thúc với:

private bool IsMobileNumberValid(string mobileNumber) 
    { 
     // remove all non-numeric characters 
     _mobileNumber = CleanNumber(mobileNumber); 

     // trim any leading zeros 
     _mobileNumber = _mobileNumber.TrimStart(new char[] { '0' }); 

     // check for this in case they've entered 44 (0)xxxxxxxxx or similar 
     if (_mobileNumber.StartsWith("440")) 
     { 
      _mobileNumber = _mobileNumber.Remove(2, 1); 
     } 

     // add country code if they haven't entered it 
     if (!_mobileNumber.StartsWith("44")) 
     { 
      _mobileNumber = "44" + _mobileNumber; 
     } 

     // check if it's the right length 
     if (_mobileNumber.Length != 12) 
     { 
      return false; 
     } 

     return true; 
    } 

    private string CleanNumber(string phone) 
    { 
     Regex digitsOnly = new Regex(@"[^\d]"); 
     return digitsOnly.Replace(phone, ""); 
    } 
+1

Cắt số 0 đứng đầu thay vì thay thế "0044". –

+0

Điểm tuyệt vời, tôi đã chỉnh sửa nó ngay bây giờ, cảm ơn! – annelie

+1

Bạn không thể chỉ cắt các số 0 đứng đầu vì "0712345678" sẽ trở thành "712345678". Ngoài ra number.Trim sẽ cắt trailing và số 0 hàng đầu, đó là ý tưởng tồi quá. – Polyfun

Trả lời

2

Sử dụng cụm từ thông dụng để xóa bất kỳ ký tự không phải số nào thay vì cố đoán xem một người sẽ nhập số của họ như thế nào - điều này sẽ xóa tất cả các phương thức Replace() và Trim() của bạn, trừ khi bạn thực sự cần phải cắt số không.

string CleanPhone(string phone) 
{ 
    Regex digitsOnly = new Regex(@"[^\d]"); 
    return digitsOnly.Replace(phone, ""); 
} 

Ngoài ra, tôi sẽ khuyên bạn sử dụng một hộp đeo mặt nạ để thu thập cáC# (có rất nhiều tùy chọn có sẵn) chỉ cho phép nhập số, và hiển thị các đầu vào với bất cứ định dạng mà bạn muốn. Bằng cách này, bạn đảm bảo rằng giá trị nhận được sẽ là tất cả các ký tự số.

+0

Tài liệu tôi có cho cổng SMS được chỉ định 44xxxxxxxxxx làm định dạng để gửi số, có thể là chúng sẽ chấp nhận +44, 0044 và 0xxxxxxxxx. Tuy nhiên, chúng tôi muốn họ có thể nhập bất kỳ hình thức nào trong số này trên biểu mẫu và ngay cả khi họ nhập số không phải ở Vương quốc Anh, chúng tôi vẫn cần đảm bảo rằng văn bản chỉ được gửi tới số của Vương quốc Anh.Có lẽ một sự kết hợp của điều này và các phương pháp cắt và thay thế là con đường để đi? – annelie

+0

Nếu bạn cần chấp nhận nhiều định dạng khác nhau, thì hộp văn bản đeo mặt nạ có thể không phải là cách để đi, vì tôi không thể nghĩ ra cách để làm cho nó đủ chung cho các yêu cầu của bạn. Tuy nhiên, phương thức trên sẽ rất hữu ích để loại bỏ bất kỳ ký tự không phải số nào từ chuỗi đầu vào. – Keith

+0

Đúng, đã làm việc điều trị, cảm ơn! Tôi sẽ cập nhật mã mới của mình. – annelie

0

@annelie có lẽ bạn có thể cập nhật biểu hiện thường xuyên của bạn đến một mạnh mẽ hơn. Kiểm tra trang web này here. Nó chứa nhiều biểu thức nhưng tôi nghĩ một trong 2 biểu thức hàng đầu trong trang web phải phù hợp với bạn.

0
public class PhoneNumber 
{ 
    public PhoneNumber(string value) 
    { 
     if (String.IsNullOrEmpty(value)) 
      throw new ArgumentNullException("numberString", Properties.Resources.PhoneNumberIsNullOrEmpty); 

     var match = new Regex(@"\+(\w+) \((\w+)\) (\w+)", RegexOptions.Compiled).Match(value); 
     if (match.Success) 
     { 
      ushort countryCode = 0; 
      ushort localCode = 0; 
      int number = 0; 

      if (UInt16.TryParse(match.Result("$1"), out countryCode) && 
       UInt16.TryParse(match.Result("$2"), out localCode) && 
       Int32.TryParse(match.Result("$3"), out number)) 
      { 
       this.CountryCode = countryCode; 
       this.LocalCode = localCode; 
       this.Number = number; 
      } 
     } 
     else 
     { 
      throw new ArgumentNullException("numberString", Properties.Resources.PhoneNumberInvalid); 
     } 
    } 

    public PhoneNumber(int countryCode, int localCode, int number) 
    { 
     if (countryCode == 0) 
      throw new ArgumentOutOfRangeException("countryCode", Properties.Resources.PhoneNumberIsNullOrEmpty); 
     else if (localCode == 0) 
      throw new ArgumentOutOfRangeException("localCode", Properties.Resources.PhoneNumberIsNullOrEmpty); 
     else if (number == 0) 
      throw new ArgumentOutOfRangeException("number", Properties.Resources.PhoneNumberIsNullOrEmpty); 

     this.CountryCode = countryCode; 
     this.LocalCode = localCode; 
     this.Number = number; 
    } 

    public int CountryCode { get; set; } 

    public int LocalCode { get; set; } 

    public int Number { get; set; } 

    public override string ToString() 
    { 
     return String.Format(System.Globalization.CultureInfo.CurrentCulture, "+{0} ({1}) {2}", CountryCode, LocalCode, Number); 
    } 

    public static bool Validate(string value) 
    { 
     return new Regex(@"\+\w+ \(\w+\) \w+", RegexOptions.Compiled).IsMatch(value); 
    } 

    public static bool Validate(string countryCode, string localCode, string number, out PhoneNumber phoneNumber) 
    { 
     var valid = false; 
     phoneNumber = null; 
     try 
     { 
      ushort uCountryCode = 0; 
      ushort uLocalCode = 0; 
      int iNumber = 0; 

      // match only if all three numbers have been parsed successfully 
      valid = UInt16.TryParse(countryCode, out uCountryCode) && 
        UInt16.TryParse(localCode, out uLocalCode) && 
        Int32.TryParse(number, out iNumber); 

      if (valid) 
       phoneNumber = new PhoneNumber(uCountryCode, uLocalCode, iNumber); 
     } 
     catch (ArgumentException) 
     { 
      // still not match 
     } 
     return valid; 
    } 
} 
Các vấn đề liên quan