C#で文字列を電話番号としてフォーマットする方法


163

文字列 "1112224444"があります。これは電話番号です。ファイルに保存する前に111-222-4444としてフォーマットしたいと思います。これはデータレコードにあり、新しいレコードを割り当てずにこれを実行できるようにしたいと思います変数。

私が考えていた:

String.Format("{0:###-###-####}", i["MyPhone"].ToString() );

しかし、それでうまくいくようには見えません。

**更新**

OK。私はこの解決策に行きました

Convert.ToInt64(i["Customer Phone"]).ToString("###-###-#### ####")

内線番号が4桁未満の場合、混乱する。右から数字が入ります。そう

1112224444 333  becomes

11-221-244 3334

何か案は?


5
すべての場所に10桁の電話番号があるわけではなく、111-222-4444形式を使用しているわけではないことに注意してください。
Dour High Arch

これは、0で始まる電話番号で失敗します
dano

これが北米の番号のみかどうかを指定する必要があります。
Armstrongest

警告:スレッド全体は、北米の電話番号を想定しています。国際番号をサポートするライブラリを使用します。nuget.org/packages/libphonenumber-csharp
Sean Anderson

回答:


204

この回答は数値データ型(int、long)で機能することに注意してください。文字列で開始する場合は、最初に文字列を数値に変換する必要があります。また、最初の文字列の長さが10文字以上であることを検証する必要があることを考慮してください。

例が豊富な良いページから:

String.Format("{0:(###) ###-####}", 8005551212);

    This will output "(800) 555-1212".

正規表現はもっとうまく機能するかもしれませんが、古いプログラミングの引用を覚えておいてください:

一部の人々は、問題に直面したときに「わかっている、私は正規表現を使用する」と考えています。今、彼らは2つの問題を抱えています。
--Jamie Zawinski、comp.lang.emacs内


電話番号に「800555」などのように数桁の数字がない場合はどうなりますか?そこにあるものだけを表示する方法はありますか?
VoodooChild 2011年

11
市外局番が0105555555などで始まる場合、最終的に(010)555-5555ではなく(01)555-5555が返されるため、これは不適切な実装です。その理由は、電話番号を数値に変換すると、先頭のゼロは何もないと見なされ、フォーマットすると最初の0が削除されるためです。
ポールメンドーサ

3
@Paul問題の定義を読んでください:「文字列があります "1112224444"電話番号です。ファイルに保存する前に、111-222-4444としてフォーマットしたいのですが。」
Sean

39
最初に数値に変換しない限り、質問にあるように、電話番号が文字列の場合、これは機能しません。
JustinStolle、2011

4
私はこれが上のコメントを繰り返すだけであることを知っていますが、この答えは質問に答えませんでした。文字列を特定の形式、この場合は電話番号形式にどのようにフォーマットしますか。
dyslexicanaboko

168

私は正規表現を使用することを好みます:

Regex.Replace("1112224444", @"(\d{3})(\d{3})(\d{4})", "$1-$2-$3");

4
これでうまくいくと思いますが、.ToString()形式の方が読みやすく、パフォーマンスも優れています。
Joel Coehoorn、2008年

14
すでに文字列を扱っているのであれば、ポスターが言ったように、それを長い文字列にキャストし、再び戻すのはばかげているようです。
Ryan Duffield

たぶん、これが結局のところ必要なのかもしれません。拡張機能の処理が向上する可能性があります
Brian G

5
番号を文字列として保持するための+1(多くの場合、自動SMSシステムに使用される電話番号は+44形式で保存する必要があります)
Ed James

3
さまざまな形式((111)222-4444、111.222.4444など)を使用していますが、(111)222-4444に正規化する必要があります。また、不完全な数値から保護するため、{n、m}表記を使用しました。(そして、フォーマットについてお詫びしますが、一部のMDフォーマットは私にとって機能しません)。 // Remove non-digit characters var phoneDigits = Regex.Replace(crewMember.CellPhone, "[^\\d]", string.Empty); // Format the digits var phone = Regex.Replace(phoneDigits, @"(\d{1,3})(\d{0,3})(\d{0,4})", " ($1) $2-$3");
Craig Boland

46

それを部分文字列に分割する必要があります。追加の変数なしでそれを行うことができます、それは特に良いことではありません。考えられる解決策の1つを次に示します。

string phone = i["MyPhone"].ToString();
string area = phone.Substring(0, 3);
string major = phone.Substring(3, 3);
string minor = phone.Substring(6);
string formatted = string.Format("{0}-{1}-{2}", area, major, minor);

Jonは、string.formatを使用するよりも3つの部分文字列を作成する方が良いと確信していますか?
Pradeep、

私もString.Formatを使用していますが、String.Formatを使用せずに結果を達成することをどのように提案していますか?
Jon Skeet、

2
それをあるif (phone.Length == 10)状態で包みました。
ザックピーターソン

プラスワン-小さな点が1つあります。その形式は、市外局番をかっこで囲んでいるようには見えません。おそらく間違って読んでいるようです。
マークロジャース

1
@MarkRogers:「111-222-4444の形式にしたい」という質問には、括弧がありません。
Jon Skeet

28

私はこれを米国の数値のクリーンな解決策として提案します。

public static string PhoneNumber(string value)
{ 
    if (string.IsNullOrEmpty(value)) return string.Empty;
    value = new System.Text.RegularExpressions.Regex(@"\D")
        .Replace(value, string.Empty);
    value = value.TrimStart('1');
    if (value.Length == 7)
        return Convert.ToInt64(value).ToString("###-####");
    if (value.Length == 10)
        return Convert.ToInt64(value).ToString("###-###-####");
    if (value.Length > 10)
        return Convert.ToInt64(value)
            .ToString("###-###-#### " + new String('#', (value.Length - 10)));
    return value;
}

1
最初に電話の値がNULLまたは空白文字でないことを確認するチェックを追加する必要があることを除いて、これは私にとってはうまくいきました。
Caverman

1
これは私が試した上記のすべての後に機能しました
Eliotjse

22

私が知る限り、これをstring.Formatで行うことはできません...これは自分で処理する必要があります。数値以外の文字をすべて取り除いて、次のようにすることができます。

string.Format("({0}) {1}-{2}",
     phoneNumber.Substring(0, 3),
     phoneNumber.Substring(3, 3),
     phoneNumber.Substring(6));

これは、データが正しく入力されていることを前提としています。正規表現を使用して検証できます。


4
そして、それは北アメリカの電話番号を仮定します
クリス

19

これはうまくいくはずです:

String.Format("{0:(###)###-####}", Convert.ToInt64("1112224444"));

またはあなたの場合:

String.Format("{0:###-###-####}", Convert.ToInt64("1112224444"));

3
01213456789を使用している場合の1つの小さな問題は、(12)345-6789 ...解決策...?
Sangram Nandkhile 2011年

5
これが最良の解決策です。先頭の0は、0または1で始まるアメリカの市外局番がないため、アメリカの電話番号に関しては意味がありません。
JB

12345678を試した場合の小さな問題(1)234-5678のフォーマット...しかし、必要なのは(123)456-78です。これに対する解決策はありますか?ありがとう
Kavitha P.

14

i["MyPhone"]として取得longできる場合は、long.ToString()メソッドを使用してフォーマットできます。

Convert.ToLong(i["MyPhone"]).ToString("###-###-####");

数値フォーマット文字列に関するMSDNページを参照してください

intではなくlongを使用するように注意してください。intはオーバーフローする可能性があります。


1
この問題は、数字が10文字より長い場合(つまり、拡張子が含まれる場合)です。これにより、212-555-1212 x1234が次のように現れる非常に奇妙な表現になります2125551-212-1234.
Michael Blackburn

5
static string FormatPhoneNumber( string phoneNumber ) {

   if ( String.IsNullOrEmpty(phoneNumber) )
      return phoneNumber;

   Regex phoneParser = null;
   string format     = "";

   switch( phoneNumber.Length ) {

      case 5 :
         phoneParser = new Regex(@"(\d{3})(\d{2})");
         format      = "$1 $2";
       break;

      case 6 :
         phoneParser = new Regex(@"(\d{2})(\d{2})(\d{2})");
         format      = "$1 $2 $3";
       break;

      case 7 :
         phoneParser = new Regex(@"(\d{3})(\d{2})(\d{2})");
         format      = "$1 $2 $3";
       break;

      case 8 :
         phoneParser = new Regex(@"(\d{4})(\d{2})(\d{2})");
         format      = "$1 $2 $3";
       break;

      case 9 :
         phoneParser = new Regex(@"(\d{4})(\d{3})(\d{2})(\d{2})");
         format      = "$1 $2 $3 $4";
       break;

      case 10 :
         phoneParser = new Regex(@"(\d{3})(\d{3})(\d{2})(\d{2})");
         format      = "$1 $2 $3 $4";
       break;

      case 11 :
         phoneParser = new Regex(@"(\d{4})(\d{3})(\d{2})(\d{2})");
         format      = "$1 $2 $3 $4";
       break;

      default:
        return phoneNumber;

   }//switch

   return phoneParser.Replace( phoneNumber, format );

}//FormatPhoneNumber

    enter code here

入力:1234567890出力:123 456 78 90が機能しない
MC9000

5

リアルタイムで変換される(米国)電話番号をお探しの場合。この拡張機能を使用することをお勧めします。この方法は、数値を逆に入力しなくても完全に機能します。String.Format解決策は、作業後方に表示されます。この拡張子を文字列に適用するだけです。

public static string PhoneNumberFormatter(this string value)
{
    value = new Regex(@"\D").Replace(value, string.Empty);
    value = value.TrimStart('1');

    if (value.Length == 0)
        value = string.Empty;
    else if (value.Length < 3)
        value = string.Format("({0})", value.Substring(0, value.Length));
    else if (value.Length < 7)
        value = string.Format("({0}) {1}", value.Substring(0, 3), value.Substring(3, value.Length - 3));
    else if (value.Length < 11)
        value = string.Format("({0}) {1}-{2}", value.Substring(0, 3), value.Substring(3, 3), value.Substring(6));
    else if (value.Length > 10)
    {
        value = value.Remove(value.Length - 1, 1);
        value = string.Format("({0}) {1}-{2}", value.Substring(0, 3), value.Substring(3, 3), value.Substring(6));
    }
    return value;
}

前進運動に最適です。しかし、戻ってきたとき、それは(###)の最初のフォーマットで行き詰まっています。
Schwagmister

@Schwagmister良いキャッチ。これは修正され、一般的な使用のためにコードを拡張機能にリファクタリングしました。
James Copeland

4

これを試すこともできます:

  public string GetFormattedPhoneNumber(string phone)
        {
            if (phone != null && phone.Trim().Length == 10)
                return string.Format("({0}) {1}-{2}", phone.Substring(0, 3), phone.Substring(3, 3), phone.Substring(6, 4));
                return phone;
        }

出力:

ここに画像の説明を入力してください


1
国によって電話番号の形式と長さが異なり、ユーザーが入力できないことに注意してください。
Neme 2017

Html.DisplayFor(model => model.PhoneNumber)でこれをどのように使用しますか?
JustJohn

私はこれを使用して、Razorページの表示でそれを使用する方法を理解しました。ページの上部にある@functions {}ブロックに配置します。次に、@ Html.DisplayForヘルパーを削除し、関数を参照しました:................. @GetFormattedPhoneNumber(Model.Courses_New.CurrentContactPhone)一日を過ごしました!
JustJohn

4

市外局番とメインの番号ブロックの間のあらゆる種類の区切り記号(例:スペース、ダッシュ、ピリオド、ect ...)を使用して電話番号を入力しようとしている状況に遭遇するかもしれません。そのため、数字以外のすべての文字の入力を除去して、作業中の入力を滅菌できるようにします。これを行う最も簡単な方法は、RegEx式を使用することです。

string formattedPhoneNumber = new System.Text.RegularExpressions.Regex(@"\D")
    .Replace(originalPhoneNumber, string.Empty);

次に、リストした回答がほとんどの場合に機能するはずです。

内線の問題についてあなたが持っているものに答えるために、(通常の電話番号の)予想される長さの10よりも長いものをすべて取り除き、それを使用して末尾に追加できます

formattedPhoneNumber = Convert.ToInt64(formattedPhoneNumber)
     .ToString("###-###-#### " + new String('#', (value.Length - 10)));

これを行う前に、入力の長さが10より大きいかどうかを判別するために「if」チェックを実行する必要があります。そうでない場合は、以下を使用します。

formattedPhoneNumber = Convert.ToInt64(value).ToString("###-###-####");

3
Function FormatPhoneNumber(ByVal myNumber As String)
    Dim mynewNumber As String
    mynewNumber = ""
    myNumber = myNumber.Replace("(", "").Replace(")", "").Replace("-", "")
    If myNumber.Length < 10 Then
        mynewNumber = myNumber
    ElseIf myNumber.Length = 10 Then
        mynewNumber = "(" & myNumber.Substring(0, 3) & ") " &
                myNumber.Substring(3, 3) & "-" & myNumber.Substring(6, 3)
    ElseIf myNumber.Length > 10 Then
        mynewNumber = "(" & myNumber.Substring(0, 3) & ") " &
                myNumber.Substring(3, 3) & "-" & myNumber.Substring(6, 3) & " " &
                myNumber.Substring(10)
    End If
    Return mynewNumber
End Function

投票されましたが、これはvb.netの回答であり、質問はc#です

入力:1234567890出力:(123)456-789動作しません!
MC9000


2

これを試して

string result;
if ( (!string.IsNullOrEmpty(phoneNumber)) && (phoneNumber.Length >= 10 ) )
    result = string.Format("{0:(###)###-"+new string('#',phoneNumber.Length-6)+"}",
    Convert.ToInt64(phoneNumber)
    );
else
    result = phoneNumber;
return result;

乾杯。


2

正規表現の一致を使用して分割し、match.groupsでフォーマットされた文字列を出力します

Regex regex = new Regex(@"(?<first3chr>\d{3})(?<next3chr>\d{3})(?<next4chr>\d{4})");
Match match = regex.Match(phone);
if (match.Success) return "(" + match.Groups["first3chr"].ToString() + ")" + " " + 
  match.Groups["next3chr"].ToString() + "-" + match.Groups["next4chr"].ToString();

2

以下は正規表現を使用せずに動作します

string primaryContactNumber = !string.IsNullOrEmpty(formData.Profile.Phone) ? String.Format("{0:###-###-####}", long.Parse(formData.Profile.Phone)) : "";

long.Parseを使用しない場合、string.formatは機能しません。


1
public string phoneformat(string phnumber)
{
String phone=phnumber;
string countrycode = phone.Substring(0, 3); 
string Areacode = phone.Substring(3, 3); 
string number = phone.Substring(6,phone.Length); 

phnumber="("+countrycode+")" +Areacode+"-" +number ;

return phnumber;
}

出力は:001-568-895623になります


1

C#http://www.beansoftware.com/NET-Tutorials/format-string-phone-number.aspxの次のリンクを使用して ください

フォーマットを行う最も簡単な方法は、正規表現を使用することです。

private string FormatPhoneNumber(string phoneNum)
{
  string phoneFormat = "(###) ###-#### x####";

  Regex regexObj = new Regex(@"[^\d]");
  phoneNum = regexObj.Replace(phoneNum, "");
  if (phoneNum.Length > 0)
  {
    phoneNum = Convert.ToInt64(phoneNum).ToString(phoneFormat);
  }
  return phoneNum;
}

電話番号を文字列2021231234として最大15文字で渡します。

FormatPhoneNumber(string phoneNum)

別のアプローチはサブストリングを使用することです

private string PhoneFormat(string phoneNum)
    {
      int max = 15, min = 10;
      string areaCode = phoneNum.Substring(0, 3);
      string mid = phoneNum.Substring(3, 3);
      string lastFour = phoneNum.Substring(6, 4);
      string extension = phoneNum.Substring(10, phoneNum.Length - min);
      if (phoneNum.Length == min)
      {
        return $"({areaCode}) {mid}-{lastFour}";
      }
      else if (phoneNum.Length > min && phoneNum.Length <= max)
      {
        return $"({areaCode}) {mid}-{lastFour} x{extension}";
      }
      return phoneNum;
    }

0

拡張機能の問題に対処するには、次のようにします。

string formatString = "###-###-#### ####";
returnValue = Convert.ToInt64(phoneNumber)
                     .ToString(formatString.Substring(0,phoneNumber.Length+3))
                     .Trim();

0

古い質問を復活させるのではなく、少々複雑な設定の場合は、少なくとも少し使いやすい方法を提供できると考えました。

そのため、新しいカスタムフォーマッタを作成string.Formatすると、電話番号をlong

したがって、まずカスタムフォーマッタを作成します。

using System;
using System.Globalization;
using System.Text;

namespace System
{
    /// <summary>
    ///     A formatter that will apply a format to a string of numeric values.
    /// </summary>
    /// <example>
    ///     The following example converts a string of numbers and inserts dashes between them.
    ///     <code>
    /// public class Example
    /// {
    ///      public static void Main()
    ///      {          
    ///          string stringValue = "123456789";
    ///  
    ///          Console.WriteLine(String.Format(new NumericStringFormatter(),
    ///                                          "{0} (formatted: {0:###-##-####})",stringValue));
    ///      }
    ///  }
    ///  //  The example displays the following output:
    ///  //      123456789 (formatted: 123-45-6789)
    ///  </code>
    /// </example>
    public class NumericStringFormatter : IFormatProvider, ICustomFormatter
    {
        /// <summary>
        ///     Converts the value of a specified object to an equivalent string representation using specified format and
        ///     culture-specific formatting information.
        /// </summary>
        /// <param name="format">A format string containing formatting specifications.</param>
        /// <param name="arg">An object to format.</param>
        /// <param name="formatProvider">An object that supplies format information about the current instance.</param>
        /// <returns>
        ///     The string representation of the value of <paramref name="arg" />, formatted as specified by
        ///     <paramref name="format" /> and <paramref name="formatProvider" />.
        /// </returns>
        /// <exception cref="System.NotImplementedException"></exception>
        public string Format(string format, object arg, IFormatProvider formatProvider)
        {
            var strArg = arg as string;

            //  If the arg is not a string then determine if it can be handled by another formatter
            if (strArg == null)
            {
                try
                {
                    return HandleOtherFormats(format, arg);
                }
                catch (FormatException e)
                {
                    throw new FormatException(string.Format("The format of '{0}' is invalid.", format), e);
                }
            }

            // If the format is not set then determine if it can be handled by another formatter
            if (string.IsNullOrEmpty(format))
            {
                try
                {
                    return HandleOtherFormats(format, arg);
                }
                catch (FormatException e)
                {
                    throw new FormatException(string.Format("The format of '{0}' is invalid.", format), e);
                }
            }
            var sb = new StringBuilder();
            var i = 0;

            foreach (var c in format)
            {
                if (c == '#')
                {
                    if (i < strArg.Length)
                    {
                        sb.Append(strArg[i]);
                    }
                    i++;
                }
                else
                {
                    sb.Append(c);
                }
            }

            return sb.ToString();
        }

        /// <summary>
        ///     Returns an object that provides formatting services for the specified type.
        /// </summary>
        /// <param name="formatType">An object that specifies the type of format object to return.</param>
        /// <returns>
        ///     An instance of the object specified by <paramref name="formatType" />, if the
        ///     <see cref="T:System.IFormatProvider" /> implementation can supply that type of object; otherwise, null.
        /// </returns>
        public object GetFormat(Type formatType)
        {
            // Determine whether custom formatting object is requested. 
            return formatType == typeof(ICustomFormatter) ? this : null;
        }

        private string HandleOtherFormats(string format, object arg)
        {
            if (arg is IFormattable)
                return ((IFormattable)arg).ToString(format, CultureInfo.CurrentCulture);
            else if (arg != null)
                return arg.ToString();
            else
                return string.Empty;
        }
    }
}

したがって、これを使用したい場合は、次のようにします。

String.Format(new NumericStringFormatter(),"{0:###-###-####}", i["MyPhone"].ToString());

考慮すべきその他の事柄:

現在のところ、フォーマットする文字列よりも長いフォーマッタを指定した場合、追加の#記号は無視されます。たとえば、これString.Format(new NumericStringFormatter(),"{0:###-###-####}", "12345");は123-45-になるので、コンストラクターである種の可能なフィラー文字を取得することができます。

また、私は#記号をエスケープする方法を提供しなかったので、出力文字列に#記号を含めたい場合、現在の方法を使用できません。

正規表現よりもこの方法を好む理由は、ユーザーが自分で形式を指定できるようにする必要があることが多く、ユーザーの正規表現を教えるよりも、この形式の使用方法を説明する方がはるかに簡単だからです。

また、クラス名は、文字列を同じ順序で保持し、その中に文字を挿入するだけであれば、実際には任意の文字列をフォーマットするために機能するので、少し間違っています。



0

これを行う別の方法を次に示します。

public string formatPhoneNumber(string _phoneNum)
{
    string phoneNum = _phoneNum;
    if (phoneNum == null)
        phoneNum = "";
    phoneNum = phoneNum.PadRight(10 - phoneNum.Length);
    phoneNum = phoneNum.Insert(0, "(").Insert(4,") ").Insert(9,"-");
    return phoneNum;
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.