ما هي أفضل طريقة لتحويل أرقام الهواتف إلى التنسيق الدولي (E.164) باستخدام Java؟

StackOverflow https://stackoverflow.com/questions/187216

سؤال

ما هي أفضل طريقة لتحويل أرقام الهواتف إلى التنسيق الدولي (E.164) باستخدام Java؟

بالنظر إلى "رقم الهاتف" ومعرف البلد (على سبيل المثال رمز البلد ISO)، أود تحويله إلى رقم هاتف قياسي بالتنسيق الدولي E.164.

أنا متأكد من أنني أستطيع القيام بذلك يدويًا بسهولة تامة - لكنني لست متأكدًا من أنه سيعمل بشكل صحيح في جميع المواقف.

ما هو إطار عمل/مكتبة/أداة Java التي توصي بها لتحقيق ذلك؟

ملاحظة.يمكن أن يكون "رقم الهاتف" أي شيء يمكن للعامة التعرف عليه - مثل

* (510) 786-0404
* 1-800-GOT-MILK
* +44-(0)800-7310658

هذا الأخير هو المفضل لدي - هذه هي الطريقة التي يكتب بها بعض الأشخاص أرقامهم في المملكة المتحدة ويعني أنه يجب عليك إما استخدام +44 أو يجب عليك استخدام 0.

يجب أن يكون رقم التنسيق E.164 رقميًا بالكامل، وأن يستخدم رمز البلد الدولي الكامل (على سبيل المثال +44)

هل كانت مفيدة؟

المحلول

يوفر

وجوجل مكتبة للعمل مع أرقام الهواتف. نفس واحدة وأنها تستخدم لالروبوت

http://code.google.com/p/libphonenumber/

String swissNumberStr = "044 668 18 00"
PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
try {
  PhoneNumber swissNumberProto = phoneUtil.parse(swissNumberStr, "CH");
} catch (NumberParseException e) {
  System.err.println("NumberParseException was thrown: " + e.toString());
}

// Produces "+41 44 668 18 00"
System.out.println(phoneUtil.format(swissNumberProto, PhoneNumberFormat.INTERNATIONAL));
// Produces "044 668 18 00"
System.out.println(phoneUtil.format(swissNumberProto, PhoneNumberFormat.NATIONAL));
// Produces "+41446681800"
System.out.println(phoneUtil.format(swissNumberProto, PhoneNumberFormat.E164));

نصائح أخرى

وبالحديث عن تجربتي في كتابة هذا النوع من الأشياء، فمن الصعب جدًا القيام بذلك بموثوقية 100%.لقد كتبت بعض أكواد Java للقيام بذلك، وهي جيدة بشكل معقول في معالجة البيانات المتوفرة لدينا ولكنها لن تكون قابلة للتطبيق في كل بلد.الأسئلة التي تحتاج إلى طرحها هي:

هل تعيينات الأحرف إلى الأرقام متسقة بين البلدان؟تستخدم الولايات المتحدة الكثير من هذا (على سبيل المثال 1800-GOT-MILK) ولكن في أستراليا، على سبيل المثال، فهو نادر جدًا.ما يتعين عليك فعله هو التأكد من قيامك بإجراء التعيين الصحيح للبلد المعني إذا كان يختلف (قد لا يكون كذلك).لا أعرف ما الذي تفعله البلدان التي تستخدم أبجديات مختلفة (مثل السيريلية في روسيا ودول الكتلة الشرقية السابقة)؛

عليك أن تتقبل أن الحل الخاص بك لن يكون 100% ويجب ألا تتوقع أن يكون كذلك.أنت بحاجة إلى اتباع نهج "أفضل تخمين".على سبيل المثال، لا توجد طريقة حقيقية لمعرفة أن 132345 هو رقم هاتف صالح في أستراليا، كما هو الحال 1300 123 456، ولكن هذين هما النموذجان الوحيدان المخصصان لأرقام 13xx ولا يمكن الاتصال بهما من الخارج؛

عليك أيضًا أن تسأل عما إذا كنت تريد التحقق من صحة المناطق (رموز المناطق).أعتقد أن الولايات المتحدة تستخدم نظامًا يكون فيه الرقم الثاني من رمز المنطقة هو 1 أو 0.ربما كان هذا هو الحال من قبل ولكني لست متأكدًا مما إذا كان لا يزال ساريًا.ومهما كان الأمر، فإن العديد من البلدان الأخرى سيكون لها قواعد أخرى.في أستراليا، تتكون رموز المنطقة الصالحة للهواتف الأرضية والهواتف المحمولة (الخلوية) من رقمين (الأول هو 0).08 و 03 و 04 كلها صالحة.01 ليس كذلك.كيف يمكنك تلبية ذلك؟هل تريد أن؟

تستخدم البلدان اصطلاحات مختلفة بغض النظر عن عدد الأرقام التي تكتبها.عليك أن تقرر ما إذا كنت تريد قبول شيء آخر غير "القاعدة".هذه كلها شائعة في أستراليا:

  • (02) 1234 5678
  • 02 1234 5678
  • 0411 123 123 (لكنني لم أر قط 04 1112 3456)
  • 131 123
  • 13 1123
  • 131 123
  • 1 300 123 123
  • 1300 123 123
  • 02-1234-5678
  • 1300-234-234
  • +44 78 1234 1234
  • +44 (0)78 1234 1234
  • +44-78-1234-1234
  • +44-(0)78-1234-1234
  • 0011 44 ​​78 1234 1234 (0011 هو رمز الاتصال الدولي القياسي)
  • (44) 078 1234 1234 (غير شائع)

وهذا فقط من أعلى رأسي.لدولة واحدة.في فرنسا، على سبيل المثال، من الشائع كتابة رقم الهاتف في أزواج أرقام (12 34 56 78) ويتم نطقه بهذه الطريقة أيضًا:بدلاً من:

الأمم المتحدة (واحد)، ثنائي (اثنان)، ثلاثية (ثلاثة)، ...

إنه

دوز (اثنا عشر)، ترينت-كاتر (أربعة وثلاثون)، ...

هل تريد تلبية هذا المستوى من الاختلاف الثقافي؟لا أفترض ذلك ولكن السؤال يستحق التفكير فيه فقط في حالة جعل قواعدك صارمة للغاية.

كما قد يقوم بعض الأشخاص أيضًا بإلحاق أرقام فرعية بأرقام الهواتف، ربما مع "ext" أو اختصار مشابه.هل تريد تلبية ذلك؟

آسف، لا يوجد رمز هنا.مجرد قائمة من الأسئلة التي يجب أن تطرحها على نفسك والقضايا التي يجب مراعاتها.كما قال آخرون، يمكن لسلسلة من التعبيرات العادية أن تفعل الكثير مما سبق، ولكن في النهاية تكون حقول أرقام الهاتف (في الغالب) نصًا حرًا في نهاية اليوم.

وهذا هو بلدي الحل:

public static String FixPhoneNumber(Context ctx, String rawNumber)
{
    String      fixedNumber = "";

    // get current location iso code
    TelephonyManager    telMgr = (TelephonyManager) ctx.getSystemService(Context.TELEPHONY_SERVICE);
    String              curLocale = telMgr.getNetworkCountryIso().toUpperCase();

    PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
    Phonenumber.PhoneNumber     phoneNumberProto;

    // gets the international dialling code for our current location
    String              curDCode = String.format("%d", phoneUtil.getCountryCodeForRegion(curLocale));
    String              ourDCode = "";

    if(rawNumber.indexOf("+") == 0)
    {
        int     bIndex = rawNumber.indexOf("(");
        int     hIndex = rawNumber.indexOf("-");
        int     eIndex = rawNumber.indexOf(" ");

        if(bIndex != -1)
        {
            ourDCode = rawNumber.substring(1, bIndex);
        }
        else if(hIndex != -1) 
        {               
            ourDCode = rawNumber.substring(1, hIndex);
        }
        else if(eIndex != -1)
        {
            ourDCode = rawNumber.substring(1, eIndex);
        }
        else
        {
            ourDCode = curDCode;
        }           
    }
    else
    {
        ourDCode = curDCode;
    }

    try 
    {
      phoneNumberProto = phoneUtil.parse(rawNumber, curLocale);
    } 

    catch (NumberParseException e) 
    {
      return rawNumber;
    }

    if(curDCode.compareTo(ourDCode) == 0)
        fixedNumber = phoneUtil.format(phoneNumberProto, PhoneNumberFormat.NATIONAL);
    else
        fixedNumber = phoneUtil.format(phoneNumberProto, PhoneNumberFormat.INTERNATIONAL);

    return fixedNumber.replace(" ", "");
}

وآمل أن يساعد هذا شخص لديه نفس المشكلة.

والتمتع بها واستخدامها بحرية.

شكرا على الإجابات.كما هو مذكور في السؤال الأصلي، أنا مهتم بتنسيق الرقم بالتنسيق القياسي أكثر من تحديد ما إذا كان رقم هاتف صالحًا (كما هو الحال في الرقم الأصلي).

لدي حاليًا بعض التعليمات البرمجية المصممة يدويًا والتي تأخذ سلسلة رقم هاتف (كما أدخلها المستخدم) وسياق البلد المصدر وسياق البلد المستهدف (البلد الذي يتم الاتصال منه بالرقم، والدولة التي يتم الاتصال بالرقم منها - وهذا معروف للنظام) ثم يقوم بالتحويل التالي في خطوات

  1. قم بإزالة كل المسافات البيضاء من الرقم

  2. ترجمة جميع الحروف الأبجدية إلى أرقام - باستخدام جدول بحث من الحروف إلى الأرقام (على سبيل المثال:أ-->2، ب-->2، ج-->2، د-->3) إلخ.للوحة المفاتيح (لم أكن أعلم أن بعض لوحات المفاتيح توزعها بشكل مختلف)

  3. قم بإزالة جميع علامات الترقيم - مع الحفاظ على علامة "+" السابقة سليمة إذا كانت موجودة (في حالة أن الرقم موجود بالفعل في نوع ما من التنسيق الدولي).

  4. حدد ما إذا كان الرقم يحتوي على بادئة اتصال دولية لسياق البلد - على سبيل المثال.إذا كان سياق المصدر هو المملكة المتحدة، فسأرى ما إذا كان يبدأ بـ "00" - واستبدله بـ "+".لا أتحقق حاليًا مما إذا كانت الأرقام التي تلي الرقم "00" متبوعة برمز الاتصال الدولي للبلد المستهدف.أبحث عن بادئة الاتصال الدولي لبلد المصدر في جدول البحث (على سبيل المثال:GB-->'00'، الولايات المتحدة-->'011' وما إلى ذلك.)

  5. حدد ما إذا كان الرقم يحتوي على بادئة اتصال محلية لسياق البلد - على سبيل المثال.إذا كان سياق المصدر هو المملكة المتحدة، فسأرى ما إذا كان يبدأ بـ "0" - واستبداله بـ "+" متبوعًا برمز الاتصال الدولي للبلد المستهدف.أبحث عن بادئة الاتصال المحلية لبلد المصدر في جدول البحث (على سبيل المثال:GB-->'0'، الولايات المتحدة-->'1' وما إلى ذلك)، ورمز الاتصال الدولي للبلد المستهدف في جدول بحث آخر (على سبيل المثال،'GB'='44'، US='1')

يبدو أنه يعمل مع كل ما طرحته حتى الآن - باستثناء الوضع +44(0)1234-567-890 - سأضيف فحص حالة خاصة لذلك.

لم تكن كتابتها صعبة - ويمكنني أن أضيف حالات خاصة لكل استثناء غريب أصادفه.لكني أود حقًا معرفة ما إذا كان هناك حل قياسي.

يبدو أن شركات الهاتف تتعامل مع هذا الشيء كل يوم.لا أحصل أبدًا على نتائج غير متناسقة عند طلب الأرقام باستخدام شبكة PSTN.على سبيل المثال، في الولايات المتحدة (حيث تحتوي الهواتف المحمولة على نفس رموز المنطقة مثل الخطوط الأرضية، يمكنني الاتصال بالرقم +1-123-456-7890، أو 011-1-123-456-7890 (حيث 011 هي بادئة الاتصال الدولي في US و1 هو رمز الاتصال الدولي للولايات المتحدة)، أو 1-123-456-7890 (حيث 1 هو بادئة الاتصال المحلية في الولايات المتحدة) أو حتى 456-7890 (على افتراض أنني كنت في رمز المنطقة 123 في ذلك الوقت) والحصول على نفس النتائج في كل مرة.أفترض أنه يتم تحويل هذه الأرقام المطلوبة داخليًا إلى نفس التنسيق القياسي E.164، وأن التحويل يتم بالكامل في البرنامج.

لنكون صادقين، وهذا يبدو وكأنه كنت قد حصلت على معظم قواعد غطت بالفعل.

وتنسيق +44 (0) 800 أحيانا (غير صحيح) المستخدمة في المملكة المتحدة هو مزعج وغير صالح بدقة وفقا لE.123، وهي التوصية ITU-T للكيفية التي ينبغي للظهور الأرقام. إذا لم تكن قد حصلت على نسخة من E.123 أنها تستحق نظرة.

لما يستحق، وشبكة الهاتف في حد ذاته لا دائما استخدام E.164. في كثير من الأحيان سوف تكون هناك إشارة في إشارة ISDN التي تم إنشاؤها بواسطة PBX (أو في الشبكة إذا كنت على الهاتف البخارية) الذي يحكي الشبكة ما إذا كان العدد الذي طلبه غير المحلية أو الوطنية أو الدولية.

وهذه هي مهمة صعبة جدا كما هي مكتوبة أرقام هواتف مختلفة تقريبا في كل بلد.

ونحن تستخدم للحفاظ على قائمة REGEXPs (أيدنا 19 نماذج) لتحليل 3 أجزاء من عدد وتحويلها بعد ذلك إلى تلك الأجزاء 3 "+ {1} {2} {3}".

وترتيب regexps من أكثر تحديدا أولا ومن ثم اتخاذ أول الذي نجح في التوزيع.

في بعض الدول يمكن التحقق من صحة 112 كرقم هاتف صحيح، ولكن إذا كنت عصا رمز البلد أمامه لن يكون ساري المفعول أي أكثر من ذلك. في البلدان الأخرى التي لا يمكن التحقق من صحة 112 ولكن يمكنك التحقق من صحة 911 كرقم هاتف صالح.

ولقد رأيت بعض الهواتف التي وضعت Q على المفتاح 7 و Z على مفتاح 9. رأيت بعض الهواتف التي وضعت Q وZ على المفتاح 0، وبعض التي وضعت Q وZ على المفتاح 1.

ورمز المنطقة التي كانت موجودة أمس قد لا يكون موجودا اليوم، والعكس بالعكس.

في النصف من أمريكا الشمالية (رمز البلد 1)، وحكم أرقام الثانية تستخدم لتكون 0 أو 1 لرموز المنطقة، ولكن هذا الحكم ذهبت بعيدا قبل 10 عاما.

وأنا لست على علم مكتبة القياسية أو الإطار المتاحة لتنسيق أرقام الهاتف في E.164.

والحل المستخدمة في منتجاتنا، الأمر الذي يتطلب التنسيق المقدمة PBX المتصل معرف في E.164، هو نشر ملف (جدول قاعدة البيانات) التي تحتوي على معلومات تنسيق E.164 لجميع البلدان المعمول بها. هذا له ميزة أنه يمكن تحديث التطبيق (للتعامل مع جميع الحالات الزاوية غريبة في شبكات PSTN مختلفة) ث / خارج تتطلب تغييرات على قاعدة رمز الإنتاج.

ويحتوي الجدول على صف لكل رمز البلد ومعلومات عن منطقة رمز طول وطول المشترك. قد تكون هناك مداخل متعددة لبلد اعتمادا على ما الاختلافات ممكنة مع رمز المنطقة والمشترك أطوال عدد.

وعن طريق نيوزيلندا PSTN (جزئي) الاتصال الهاتفي خطة كمثال على الطاولة ..

CC  AREA_CODE  AREA_CODE_LENGTH  SUBSCRIBER  SUBSCRIBER_LENGTH
64                            1              7
64         21                 2              7
64        275                 3              6

ونحن نفعل شيئا من هذا القبيل إلى ما كنت قد وصفت، أي تجريد رقم الهاتف المقدمة من أي أحرف غير أرقام ثم الشكل القائم على قواعد مختلفة بشأن طول العام خطة رقم، رمز وصول الخارجي، ومنذ فترة طويلة المسافة / رموز الوصول الدولية.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top