2010-03-08 36 views
6

Tôi đang cố gắng tạo ra một chức năng định dạng số điện thoại của Mỹ - hy vọng không lặp qua từng chữ số.String.Format số điện thoại với phần mở rộng

Khi 10 chữ số được chuyển thì tất cả đều ổn. Làm thế nào bao giờ khi hơn 10 chữ số được thông qua trong Tôi muốn phương pháp String.Format để nối thêm các chữ số mở rộng ở bên phải. Ví dụ:

Khi 14 chữ số được thông qua vào kết quả nên là: (444) 555-2222 x8888 Khi 12 chữ số được thông qua vào kết quả nên là: (444) 555-2222 x88 , vv Tuy nhiên những gì tôi nhận được với nỗ lực hiện tại của tôi là: Việc trả về 12 chữ số sẽ trả về chuỗi này '() -949 x555444433'

đây là những gì tôi có cho đến nay.

public static string _FormatPhone(object phonevalue) 
{ 
    Int64 phoneDigits; 

    if (Int64.TryParse(phonevalue.ToString(), out phoneDigits)) 
    { 
     string cleanPhoneDigits = phoneDigits.ToString(); 
     int digitCount = cleanPhoneDigits.Length; 

     if (digitCount == 10) 
      return String.Format("{0:(###) ###-####}", phoneDigits); 
     else if (digitCount > 10) 
      return String.Format("{0:(###) ###-#### x#########}", phoneDigits); 
     else 
      return cleanPhoneDigits; 
    } 

    return "Format Err#"; 
} 

Xin cảm ơn trước.

Trả lời

2

Tôi nghĩ bạn sẽ phải ngắt điện thoại chuỗi chữ số thành 10 chữ số đầu tiên và số còn lại.

//[snip] 
else if (phoneDigits.ToString().Length > 10) 
     { 
      return String.Format("{0:(###) ###-#### x}{1}", phoneDigits.Substring(0,10), phoneDigits.Substring(10)); 
     } 
//[snip] 
+0

Ok, nhưng nếu bạn định đi xuống đường dẫn Substring, tại sao lại dừng ở đó? –

+0

Điều này có vẻ thẳng về phía trước đủ. else if (phoneDigitString.Length> 10) { trở String.Format ( "({0}) {1} - {2} x {3}", phoneDigitString.Substring (0, 3), phoneDigitString.Substring (3, 3), phoneDigitString.Substring (3, 4), phoneDigitString.Substring (10)); } – ChiliYago

+0

Đó là cược an toàn cho rằng cách chuỗi con sẽ nhanh hơn. –

0

Hãy thử sử dụng biểu thức thông thường:

class Program 
    { 
     static void Main(string[] args) 
     { 
      var g = FormatUSPhone("444555222234"); 

     } 

     public static string FormatUSPhone(string num) 
     { 
      string results = string.Empty; 

      if(num.Length == 10) 
      { 
       num = num.Replace("(", "").Replace(")", "").Replace("-", ""); 
       const string formatPattern = @"(\d{3})(\d{3})(\d{4})"; 

       results = Regex.Replace(num, formatPattern, "($1) $2-$3"); 

      }else if (num.Length == 12) 
      { 
       num = num.Replace("(", "").Replace(")", "").Replace("-", ""); 
       const string formatPattern = @"(\d{3})(\d{3})(\d{4})(\d{2})"; 

       results = Regex.Replace(num, formatPattern, "($1) $2-$3 x$4"); 
      } 

      return results; 
     } 

tôi thay đổi nội dung trên từ một ví dụ tôi thấy here. Chơi về với các mã trên, xem nếu nó giúp bạn.

+0

Tôi sẽ xem xét regexp để được hoàn thành overkill cho ví dụ này. –

+0

@Steven Tại sao, một số điện thoại là sau tất cả các biểu thức chính quy? – BlackICE

+0

@David: Bởi vì chúng tôi có tất cả các chữ số chỉ ngồi ở đó. Không có gì để tìm kiếm, không có gì để phù hợp. Tất cả những gì chúng ta cần làm là trộn chúng với một số định dạng, và điều đó đủ dễ dàng với một StringBuffer. –

1

Tôi khuyên bạn nên coi nó như một chuỗi các chữ số chứ không phải là một số. Sau đó bạn sẽ sử dụng Substring một cách rõ ràng để phá vỡ các phần.

0

sử dụng một regex:

Regex usPhoneRegex = new Regex(@"(\d{3})(\d{3})(\d{4})(.*)", RegexOptions.IgnoreCase | RegexOptions.Compiled); 
string USPhoneFormatString = "$1-$2-$3 x$4"; 
return usPhoneRegex.Replace("312588230012999", USPhoneFormatString)); 

Bất cứ điều gì sau khi số điện thoại chính sẽ được trả lại như một phần mở rộng

Vì bạn đang sử dụng một Int64 trong mã của bạn, regex tôi giả định không có dấu cách hoặc dấu chấm câu trong số điện thoại.

- Chỉnh sửa - Ahmad đã chỉ ra rằng tôi đã không xử lý trường hợp của một số không có phần mở rộng. Vì vậy, đây là một phiên bản sửa đổi sử dụng một MatchEvaluator để thực hiện công việc. Nó có tốt hơn các câu trả lời khác không? Tôi không biết - nhưng đó là một cách tiếp cận khác vì vậy tôi nghĩ tôi sẽ ném nó ra khỏi đó.

Regex usPhoneRegex = new Regex(@"(\d{3})(\d{3})(\d{4})(.*)", RegexOptions.IgnoreCase | RegexOptions.Compiled); 
return usPhoneRegex.Replace("3125882300", new MatchEvaluator(MyClass.formatPhone)) 

public static string formatPhone(Match m) { 
    int groupIndex = 0; 
    string results = string.Empty; 
    foreach (Group g in m.Groups) { 
    groupIndex +=1; 
    switch (groupIndex) { 
     case 2 : 
     results = g.Value; 
     break; 
     case 3 : 
     case 4 : 
     results += "-" + g.Value; 
     break; 
     case 5 : 
     if (g.Value.Length != 0) { 
      results += " x " + g.Value; 
     } 
     break; 
    } 
    } 
    return results; 
} 

Điều này có lẽ nên sử dụng trình tạo StringBuilder.

+0

Điều này không xử lý trường hợp 10 chữ số được sử dụng và '$ 4' trống, trả về kết quả bằng dấu" x ":' 312-588-2300 x' –

+0

@Ahmad - điểm tốt - tôi đang chỉnh sửa đáp ứng với một cách tiếp cận regex khác, sử dụng một MatchEvaluator chỉ để xem nó hoạt động như thế nào. – Ray

0

Sự cố nằm trong điều kiện else if của bạn, nơi bạn có một số bộ giữ chỗ # để xử lý tiện ích mở rộng số điện thoại. Thay vào đó, chúng tôi có thể xác định định dạng động để tính toán các độ dài khác nhau.

Tại sao bạn đi qua một số object? Bạn đang sử dụng ToString() khắp nơi. Tại sao không vượt qua trong một string từ đầu? Nếu mặt hàng bạn đang đi qua không phải là một chuỗi thì hãy gọi ToString trước khi chuyển nó vào hoặc lưu kết quả ToString() vào một biến trong phương thức như được hiển thị bên dưới.

Dưới đây là một phiên bản cập nhật của phương pháp của bạn:

public static string _FormatPhone(object phonevalue) 
{ 
    string returnPhone = "Format Err#"; 

    Int64 phoneDigits; 
    string phoneNumber = phonevalue.ToString(); 

    if (Int64.TryParse(phoneNumber, out phoneDigits)) 
    { 
     if (phoneNumber.Length == 10) 
     { 
      return phoneDigits.ToString("(###) ###-####"); 
     } 
     else if (phoneNumber.Length > 10) 
     { 
      // determine the length of placeholders needed for the format 
      string format = "(###) ###-#### x" 
           + new string('#', phoneNumber.Length - 10); 
      return phoneDigits.ToString(format); 
     } 
     else 
     { 
      return phoneNumber; 
     } 
    } 

    return returnPhone; 
} 

Để kiểm tra nó:

string[] inputs = { "456", "4445552222", "444555222288", "44455522226789" }; 
foreach (string input in inputs) 
{ 
    Console.WriteLine("Format Result: " + _FormatPhone(input)); 
} 

Không cần cho một regex trong trường hợp này. Nếu bạn thực sự muốn sử dụng một trong, mặc dù phương pháp thay thế của bạn cần phải xác định độ dài để thêm phần mở rộng khi cần thiết như hình dưới đây:

string[] inputs = { "456", "4445552222", "444555222288", "44455522226789" }; 
string pattern = @"(\d{3})(\d{3})(\d{4})(\d*)"; 
foreach (string input in inputs) 
{ 
    string result = Regex.Replace(input, pattern, m => 
    { 
     if (m.Value.Length >= 10) 
     { 
      return String.Format("({0}) {1}-{2}", 
       m.Groups[1].Value, m.Groups[2].Value, m.Groups[3].Value) 
        + (m.Value.Length > 10 ? " x" + m.Groups[4].Value : ""); 
     } 
     return m.Value; 
    }); 
    Console.WriteLine("Regex result: " + result); 
} 
1

Cố gắng ép nó vào 1 dòng, tôi đã đưa ra với điều này.

var phoneNumber = "(999) 555-4455 ext123"; 
phoneNumber = Regex.Replace(phoneNumber, "(.*?)([+]\\d{1,3})?(.*?)(\\d{3})(.*?)(\\d{3})(.*?)(\\d{4})([ ]+)?(x|ext)?(.*?)(\\d{2,5})?(.*?)$", "$2 $4 $6 $8 $10$12").Trim().Replace("ext","x"); 

Nếu nó bắt đầu bằng dấu + #, nó sẽ để nguyên điều đó. Sau đó nó sẽ tìm các khối số. 3,3,4 sau đó nó cho ext hoặc x cho phần mở rộng và một số 2-5. Tại thời điểm đó bạn có thể định dạng nó dù sao bạn thích, tôi đã chọn không gian.

1234567890 -> '123 456 7890'

(123) 456,7890 -> '123 456 7890'

+1 (999)555-4455 ext123 -> '+1 999 555 4455 x123'

Các vấn đề liên quan