Formatieren von Telefonnummern in PHP


101

Ich arbeite an einer SMS-App und muss in der Lage sein, die Telefonnummer des Absenders von +11234567890 in 123-456-7890 zu konvertieren, damit sie mit Datensätzen in einer MySQL-Datenbank verglichen werden kann .

Die Nummern werden im letzteren Format gespeichert, um sie an anderer Stelle auf der Website zu verwenden, und ich möchte dieses Format lieber nicht ändern, da dafür viel Code geändert werden müsste.

Wie würde ich das mit PHP machen?

Vielen Dank!


13
ahhhhh .... NOOOO .... warum speicherst du solche Telefonnummern? als String? Schlecht schlecht schlecht! Sie sollten sie als große Ints speichern ... weniger Speicher erforderlich, schnellerer Index, schnelleres Sortieren
Sethvargo

7
Nicht so sehr ein Problem beim Speichern von Telefonnummern als von Zeichenfolgen (kann nicht vermieden werden, wenn Sie +61 (0) 812345678 speichern müssen) - aber das Speichern eines bestimmten Formats ist etwas zwielichtig (dh die Trennzeichen) - am besten formatieren auf der Präsentationsschicht und nicht auf der Datenschicht.
HorusKol

3
@ NightMICU - das ist 100% der falsche Weg, um das zu tun ... Sie sollten als Ganzzahl speichern und eine wiederverwendbare Funktion haben, die für die Anzeige
formatiert

227
Das Speichern von Telefonnummern als Ganzzahlen, um Speicherplatz zu sparen, ist eine schreckliche Idee. Telefonnummern sind keine Nummern im allgemeinen Sinne, mit denen Sie rechnen können. In dem Moment, in dem Sie Zahlen außerhalb eines US-spezifischen Formats speichern müssen, in dem die Zahl mit einer 0 beginnen kann, treten Probleme auf. Speichern Sie diese Informationen besser als Zeichenfolge.
Charles Sprayberry

2
@NightMICU Wenn Sie sich beim Speichern als Zeichenfolge besser fühlen, sagt sogar der große Jon Skeet, dass er für das führende Nullproblem nicht als Ganzzahl speichern soll. stackoverflow.com/a/3483166/746010
Charles Sprayberry

Antworten:


108
$data = '+11234567890';

if(  preg_match( '/^\+\d(\d{3})(\d{3})(\d{4})$/', $data,  $matches ) )
{
    $result = $matches[1] . '-' .$matches[2] . '-' . $matches[3];
    return $result;
}

So erfassen Sie mögliche Leerzeichen und andere Formate internationaler Zahlen: / ^ (\ +? \ D {1,2}?) [.-]? (? (\ D {3}))? [.-]? (\ D. {3}) [.-]? (\ D {4}) $ /
TeckniX

3
@stoutie Sie falsch, $ Übereinstimmungen [0] ist der gesamte übereinstimmende Mustertext, dann müssen Sie array_shift ($ Übereinstimmungen), bevor Sie es auf diese Weise verwenden.
Alexandre Reis Ribeiro

Wäre es schneller, dies bei der Ausgabe zu formatieren? Verwenden sprintfoder `printf``? Jemand bitte erkläre es mir. Ich arbeite nur mit US-Telefonnummern und denke nicht, dass es die beste Methode ist, sie mithilfe von Teilzeichenfolgen durch eine Ausgabefunktion zu führen.
Rafael

Ich denke, SO sollte Downvotes zu Kommentaren enthalten. Der Kommentar von @Stoutie ist irreführend.
Peterchaula

1
Ich entschuldige mich für meine jüngeren, vor-tdd Tag selbst veröffentlichten fehlerhaften Kommentare vor so vielen Jahren. Ich verspreche, es in Zukunft besser zu machen. Der Kommentar, auf den Sie verweisen, scheint gelöscht worden zu sein. Alles ist gut. Schöne Ferien.
Stoutie

163

Dies ist ein US-Telefonformatierer, der mit mehr Versionen von Zahlen arbeitet als jede der aktuellen Antworten.

$numbers = explode("\n", '(111) 222-3333
((111) 222-3333
1112223333
111 222-3333
111-222-3333
(111)2223333
+11234567890
    1-8002353551
    123-456-7890   -Hello!
+1 - 1234567890 
');


foreach($numbers as $number)
{
    print preg_replace('~.*(\d{3})[^\d]{0,7}(\d{3})[^\d]{0,7}(\d{4}).*~', '($1) $2-$3', $number). "\n";
}

Und hier ist eine Aufschlüsselung der Regex:

Cell: +1 999-(555 0001)

.*          zero or more of anything "Cell: +1 "
(\d{3})     three digits "999"
[^\d]{0,7}  zero or up to 7 of something not a digit "-("
(\d{3})     three digits "555"
[^\d]{0,7}  zero or up to 7 of something not a digit " "
(\d{4})     four digits "0001"
.*          zero or more of anything ")"

Aktualisiert: 11. März 2015 {0,7}anstelle von{,7}


Was ist, wenn die Telefonnummer eine Nebenstelle hat?
SpYk3HH

1
Guter Punkt - haben wir einige Beispiele dafür, wie Erweiterungen auf der ganzen Welt aussehen? Wahrscheinlich so etwas wie ~.*(\d{3})[^\d]*(\d{3})[^\d]*(\d{4})(?:[ \D#\-]*(\d{3,6}))?.*~.
Xeoncross

1
Was ist, wenn meine Website-Benutzer die Vorwahl weggelassen haben?
Skibulk

Können wir eine Aufschlüsselung der verschiedenen Teile der Regex erhalten (wie unten in einer anderen Antwort gezeigt)? dh: (\d{3}) // 3 digits [\d]// Zeichen, das keine Ziffer ist
roberthuttinger

1
@WesleyMurch Es scheint eine Änderung der Übereinstimmung mit regulären Ausdrücken zu geben, auf die jetzt {,7}aktualisiert werden muss {0,7}. Ich habe den Code aktualisiert.
Xeoncross

55

Diese Funktion formatiert internationale (10+ Ziffern), nicht internationale (10 Ziffern) oder Old School (7 Ziffern) Telefonnummern. Andere Zahlen als 10+, 10 oder 7 Ziffern bleiben unformatiert.

function formatPhoneNumber($phoneNumber) {
    $phoneNumber = preg_replace('/[^0-9]/','',$phoneNumber);

    if(strlen($phoneNumber) > 10) {
        $countryCode = substr($phoneNumber, 0, strlen($phoneNumber)-10);
        $areaCode = substr($phoneNumber, -10, 3);
        $nextThree = substr($phoneNumber, -7, 3);
        $lastFour = substr($phoneNumber, -4, 4);

        $phoneNumber = '+'.$countryCode.' ('.$areaCode.') '.$nextThree.'-'.$lastFour;
    }
    else if(strlen($phoneNumber) == 10) {
        $areaCode = substr($phoneNumber, 0, 3);
        $nextThree = substr($phoneNumber, 3, 3);
        $lastFour = substr($phoneNumber, 6, 4);

        $phoneNumber = '('.$areaCode.') '.$nextThree.'-'.$lastFour;
    }
    else if(strlen($phoneNumber) == 7) {
        $nextThree = substr($phoneNumber, 0, 3);
        $lastFour = substr($phoneNumber, 3, 4);

        $phoneNumber = $nextThree.'-'.$lastFour;
    }

    return $phoneNumber;
}

Das ist großartig, aber ich möchte nur darauf hinweisen, dass die Klammern um die Vorwahl optionale Zahlen implizieren. In den meisten Ländern wird die Vorwahl nicht mehr als optional betrachtet, sodass die Trennung mit einem einfachen Bindestrich genauer ist.
Vincent

erstaunlicher Code ..!
Chandni Soni

30

Angenommen, Ihre Telefonnummern haben immer genau dieses Format, können Sie dieses Snippet verwenden:

$from = "+11234567890";
$to = sprintf("%s-%s-%s",
              substr($from, 2, 3),
              substr($from, 5, 3),
              substr($from, 8));

Echo einfach das $ zu var ... Ich liebe es, arbeitete für mich nur Präfekt.
Samuel Ramzan

22

Telefonnummern sind schwer. Für eine robustere, internationale Lösung würde ich diesen gut gepflegten PHP-Port der libphonenumber- Bibliothek von Google empfehlen .

Verwenden Sie es so,

use libphonenumber\NumberParseException;
use libphonenumber\PhoneNumber;
use libphonenumber\PhoneNumberFormat;
use libphonenumber\PhoneNumberUtil;

$phoneUtil = PhoneNumberUtil::getInstance();

$numberString = "+12123456789";

try {
    $numberPrototype = $phoneUtil->parse($numberString, "US");

    echo "Input: " .          $numberString . "\n";
    echo "isValid: " .       ($phoneUtil->isValidNumber($numberPrototype) ? "true" : "false") . "\n";
    echo "E164: " .           $phoneUtil->format($numberPrototype, PhoneNumberFormat::E164) . "\n";
    echo "National: " .       $phoneUtil->format($numberPrototype, PhoneNumberFormat::NATIONAL) . "\n";
    echo "International: " .  $phoneUtil->format($numberPrototype, PhoneNumberFormat::INTERNATIONAL) . "\n";
} catch (NumberParseException $e) {
    // handle any errors
}

Sie erhalten folgende Ausgabe:

Input: +12123456789
isValid: true
E164: +12123456789
National: (212) 345-6789
International: +1 212-345-6789

Ich würde empfehlen, das E164Format für doppelte Prüfungen zu verwenden. Sie können auch überprüfen, ob es sich bei der Nummer tatsächlich um eine Mobiltelefonnummer handelt (mit PhoneNumberUtil::getNumberType()) oder ob es sich sogar um eine US-Nummer handelt (mit PhoneNumberUtil::getRegionCodeForNumber()).

Als Bonus kann die Bibliothek so ziemlich jede Eingabe verarbeiten. Wenn Sie sich beispielsweise dafür entscheiden, 1-800-JETBLUEden obigen Code durchzugehen, erhalten Sie

Input: 1-800-JETBLUE
isValid: true
E164: +18005382583
National: (800) 538-2583
International: +1 800-538-2583

Neato.

Es funktioniert genauso gut für andere Länder als die USA. Verwenden Sie einfach einen anderen ISO-Ländercode im parse()Argument.


2
Tolle Bibliothek, aber beachten Sie, dass es 37 MB und 1500 Dateien sind! In meinem Fall muss nur eine begrenzte Anzahl von Telefonnummern number_formattedformatiert werden. Daher habe ich beschlossen, einfach eine Spalte in meine Datenbank einzufügen und die formatierten Nummern manuell einzugeben. Verwenden Sie es immer noch libphonenumberlokal, um die formatierten Zahlen zu generieren, aber das Einfügen einer so großen Bibliothek für mein kleines Projekt ist einfach übertrieben.
Magnus W

9

Hier ist meine Lösung nur für die USA mit der Vorwahl als optionaler Komponente, einem erforderlichen Trennzeichen für die Erweiterung und Regex-Kommentaren:

function formatPhoneNumber($s) {
$rx = "/
    (1)?\D*     # optional country code
    (\d{3})?\D* # optional area code
    (\d{3})\D*  # first three
    (\d{4})     # last four
    (?:\D+|$)   # extension delimiter or EOL
    (\d*)       # optional extension
/x";
preg_match($rx, $s, $matches);
if(!isset($matches[0])) return false;

$country = $matches[1];
$area = $matches[2];
$three = $matches[3];
$four = $matches[4];
$ext = $matches[5];

$out = "$three-$four";
if(!empty($area)) $out = "$area-$out";
if(!empty($country)) $out = "+$country-$out";
if(!empty($ext)) $out .= "x$ext";

// check that no digits were truncated
// if (preg_replace('/\D/', '', $s) != preg_replace('/\D/', '', $out)) return false;
return $out;
}

Und hier ist das Skript, um es zu testen:

$numbers = [
'3334444',
'2223334444',
'12223334444',
'12223334444x5555',
'333-4444',
'(222)333-4444',
'+1 222-333-4444',
'1-222-333-4444ext555',
'cell: (222) 333-4444',
'(222) 333-4444 (cell)',
];

foreach($numbers as $number) {
    print(formatPhoneNumber($number)."<br>\r\n");
}

5

Hier ist eine einfache Funktion zum Formatieren von Telefonnummern mit 7 bis 10 Ziffern auf europäischere (oder schwedischere?) Weise:

function formatPhone($num) {
    $num = preg_replace('/[^0-9]/', '', $num);
    $len = strlen($num);

    if($len == 7) $num = preg_replace('/([0-9]{2})([0-9]{2})([0-9]{3})/', '$1 $2 $3', $num);
    elseif($len == 8) $num = preg_replace('/([0-9]{3})([0-9]{2})([0-9]{3})/', '$1 - $2 $3', $num);
    elseif($len == 9) $num = preg_replace('/([0-9]{3})([0-9]{2})([0-9]{2})([0-9]{2})/', '$1 - $2 $3 $4', $num);
    elseif($len == 10) $num = preg_replace('/([0-9]{3})([0-9]{2})([0-9]{2})([0-9]{3})/', '$1 - $2 $3 $4', $num);

    return $num;
}

5

Das Rad nicht neu erfinden! Importieren Sie diese erstaunliche Bibliothek:
https://github.com/giggsey/libphonenumber-for-php

$defaultCountry = 'SE'; // Based on the country of the user
$phoneUtil = PhoneNumberUtil::getInstance();
$swissNumberProto = $phoneUtil->parse($phoneNumber, $defaultCountry);

return $phoneUtil->format($swissNumberProto, PhoneNumberFormat::INTERNATIONAL);

Es basiert auf der Google-Bibliothek zum Parsen, Formatieren und Überprüfen internationaler Telefonnummern: https://github.com/google/libphonenumber


3
Ich denke, dies ist eine gültige Antwort, aber wenn Sie möchten, dass sie gemäß den Stack Overflow-Standards nützlich ist, sollten Sie sie so bearbeiten, dass sie ein Beispiel zur Lösung des OP-Problems mithilfe der Bibliothek enthält, anstatt nur einen Link freizugeben.
Alecg_O

1
Vielen Dank, dass Sie @Alecg_O! Ich habe ein Beispiel hinzugefügt.
Viktor Jarnheimer

4

Ich sehe, dass dies entweder mit einem regulären Ausdruck oder einigen Substrat-Aufrufen möglich ist (vorausgesetzt, die Eingabe hat immer dieses Format und ändert die Länge nicht usw.).

etwas wie

$in = "+11234567890"; $output = substr($in,2,3)."-".substr($in,6,3)."-".substr($in,10,4);

Sollte es tun.


4

Es ist schneller als RegEx.

$input = "0987654321"; 

$output = substr($input, -10, -7) . "-" . substr($input, -7, -4) . "-" . substr($input, -4); 
echo $output;

1
Kurz und bündig (y).
Rahim.nagori

2

Versuchen Sie etwas wie:

preg_replace('/\d{3}/', '$0-', str_replace('.', null, trim($number)), 2);

Dies würde eine $ -Zahl von dauern 8881112222und in konvertieren 888-111-2222. Hoffe das hilft.


1
Quelle Ihres Vorschlags: hotscripts.com/forums/php/36805-php-format-phone-numbers.html . Der str_replace von '.'sollte ebenfalls aktualisiert '-'oder entfernt werden. Es wurde aufgrund des jeweiligen Anwendungsfalls aufgenommen - mit sehr geringem Aufwand hätten Sie es konvertieren preg_replace('/\d{3}/', '$0-', substr($number, 2))und die Frage direkt beantworten können.
Iiridayn

2

Eine weitere Option - einfach zu aktualisieren, um ein Format aus der Konfiguration zu erhalten.

$numbers = explode("\n", '(111) 222-3333
((111) 222-3333
1112223333
111 222-3333
111-222-3333
(111)2223333
+11234567890
    1-8002353551
    123-456-7890   -Hello!
+1 - 1234567890
');
foreach( $numbers AS $number ){
  echo comMember_format::phoneNumber($number) . '<br>';
}

// ************************************************************************
// Format Phone Number
public function phoneNumber( $number ){
  $txt = preg_replace('/[\s\-|\.|\(|\)]/','',$number);
  $format = '[$1?$1 :][$2?($2):x][$3: ]$4[$5: ]$6[$7? $7:]';
  if( preg_match('/^(.*)(\d{3})([^\d]*)(\d{3})([^\d]*)(\d{4})([^\d]{0,1}.*)$/', $txt, $matches) ){
    $result = $format;
    foreach( $matches AS $k => $v ){
      $str = preg_match('/\[\$'.$k.'\?(.*?)\:(.*?)\]|\[\$'.$k.'\:(.*?)\]|(\$'.$k.'){1}/', $format, $filterMatch);
      if( $filterMatch ){
        $result = str_replace( $filterMatch[0], (!isset($filterMatch[3]) ? (strlen($v) ? str_replace( '$'.$k, $v, $filterMatch[1] ) : $filterMatch[2]) : (strlen($v) ? $v : (isset($filterMatch[4]) ? '' : (isset($filterMatch[3]) ? $filterMatch[3] : '')))), $result );
      }
    }
    return $result;
  }
  return $number;
}

1

Alles,

Ich glaube, ich habe es behoben. Arbeiten Sie für aktuelle Eingabedateien und haben Sie die folgenden 2 Funktionen, um dies zu erledigen!

Funktion format_phone_number:

        function format_phone_number ( $mynum, $mask ) {
        /*********************************************************************/
        /*   Purpose: Return either masked phone number or false             */
        /*     Masks: Val=1 or xxx xxx xxxx                                             */
        /*            Val=2 or xxx xxx.xxxx                                             */
        /*            Val=3 or xxx.xxx.xxxx                                             */
        /*            Val=4 or (xxx) xxx xxxx                                           */
        /*            Val=5 or (xxx) xxx.xxxx                                           */
        /*            Val=6 or (xxx).xxx.xxxx                                           */
        /*            Val=7 or (xxx) xxx-xxxx                                           */
        /*            Val=8 or (xxx)-xxx-xxxx                                           */
        /*********************************************************************/         
        $val_num        = self::validate_phone_number ( $mynum );
        if ( !$val_num && !is_string ( $mynum ) ) { 
            echo "Number $mynum is not a valid phone number! \n";
            return false;
        }   // end if !$val_num
        if ( ( $mask == 1 ) || ( $mask == 'xxx xxx xxxx' ) ) { 
            $phone = preg_replace('~.*(\d{3})[^\d]*(\d{3})[^\d]*(\d{4}).*~', 
                    '$1 $2 $3'." \n", $mynum);
            return $phone;
        }   // end if $mask == 1
        if ( ( $mask == 2 ) || ( $mask == 'xxx xxx.xxxx' ) ) { 
            $phone = preg_replace('~.*(\d{3})[^\d]*(\d{3})[^\d]*(\d{4}).*~', 
                    '$1 $2.$3'." \n", $mynum);
            return $phone;
        }   // end if $mask == 2
        if ( ( $mask == 3 ) || ( $mask == 'xxx.xxx.xxxx' ) ) { 
            $phone = preg_replace('~.*(\d{3})[^\d]*(\d{3})[^\d]*(\d{4}).*~', 
                    '$1.$2.$3'." \n", $mynum);
            return $phone;
        }   // end if $mask == 3
        if ( ( $mask == 4 ) || ( $mask == '(xxx) xxx xxxx' ) ) { 
            $phone = preg_replace('~.*(\d{3})[^\d]*(\d{3})[^\d]*(\d{4}).*~', 
                    '($1) $2 $3'." \n", $mynum);
            return $phone;
        }   // end if $mask == 4
        if ( ( $mask == 5 ) || ( $mask == '(xxx) xxx.xxxx' ) ) { 
            $phone = preg_replace('~.*(\d{3})[^\d]*(\d{3})[^\d]*(\d{4}).*~', 
                    '($1) $2.$3'." \n", $mynum);
            return $phone;
        }   // end if $mask == 5
        if ( ( $mask == 6 ) || ( $mask == '(xxx).xxx.xxxx' ) ) { 
            $phone = preg_replace('~.*(\d{3})[^\d]*(\d{3})[^\d]*(\d{4}).*~', 
                    '($1).$2.$3'." \n", $mynum);
            return $phone;
        }   // end if $mask == 6
        if ( ( $mask == 7 ) || ( $mask == '(xxx) xxx-xxxx' ) ) { 
            $phone = preg_replace('~.*(\d{3})[^\d]*(\d{3})[^\d]*(\d{4}).*~', 
                    '($1) $2-$3'." \n", $mynum);
            return $phone;
        }   // end if $mask == 7
        if ( ( $mask == 8 ) || ( $mask == '(xxx)-xxx-xxxx' ) ) { 
            $phone = preg_replace('~.*(\d{3})[^\d]*(\d{3})[^\d]*(\d{4}).*~', 
                    '($1)-$2-$3'." \n", $mynum);
            return $phone;
        }   // end if $mask == 8
        return false;       // Returns false if no conditions meet or input
    }  // end function format_phone_number

Funktion validate_phone_number:

        function validate_phone_number ( $phone ) {
        /*********************************************************************/
        /*   Purpose:   To determine if the passed string is a valid phone  */
        /*              number following one of the establish formatting        */
        /*                  styles for phone numbers.  This function also breaks    */
        /*                  a valid number into it's respective components of:      */
        /*                          3-digit area code,                                      */
        /*                          3-digit exchange code,                                  */
        /*                          4-digit subscriber number                               */
        /*                  and validates the number against 10 digit US NANPA  */
        /*                  guidelines.                                                         */
        /*********************************************************************/         
        $format_pattern =   '/^(?:(?:\((?=\d{3}\)))?(\d{3})(?:(?<=\(\d{3})\))'.
                                    '?[\s.\/-]?)?(\d{3})[\s\.\/-]?(\d{4})\s?(?:(?:(?:'.
                                    '(?:e|x|ex|ext)\.?\:?|extension\:?)\s?)(?=\d+)'.
                                    '(\d+))?$/';
        $nanpa_pattern      =   '/^(?:1)?(?(?!(37|96))[2-9][0-8][0-9](?<!(11)))?'.
                                    '[2-9][0-9]{2}(?<!(11))[0-9]{4}(?<!(555(01([0-9]'.
                                    '[0-9])|1212)))$/';

        // Init array of variables to false
        $valid = array('format' =>  false,
                            'nanpa' => false,
                            'ext'       => false,
                            'all'       => false);

        //Check data against the format analyzer
        if ( preg_match ( $format_pattern, $phone, $matchset ) ) {
            $valid['format'] = true;    
        }

        //If formatted properly, continue
        //if($valid['format']) {
        if ( !$valid['format'] ) {
            return false;
        } else {
            //Set array of new components
            $components =   array ( 'ac' => $matchset[1], //area code
                                                            'xc' => $matchset[2], //exchange code
                                                            'sn' => $matchset[3] //subscriber number
                                                            );
            //              $components =   array ( 'ac' => $matchset[1], //area code
            //                                              'xc' => $matchset[2], //exchange code
            //                                              'sn' => $matchset[3], //subscriber number
            //                                              'xn' => $matchset[4] //extension number             
            //                                              );

            //Set array of number variants
            $numbers    =   array ( 'original' => $matchset[0],
                                        'stripped' => substr(preg_replace('[\D]', '', $matchset[0]), 0, 10)
                                        );

            //Now let's check the first ten digits against NANPA standards
            if(preg_match($nanpa_pattern, $numbers['stripped'])) {
                $valid['nanpa'] = true;
            }

            //If the NANPA guidelines have been met, continue
            if ( $valid['nanpa'] ) {
                if ( !empty ( $components['xn'] ) ) {
                    if ( preg_match ( '/^[\d]{1,6}$/', $components['xn'] ) ) {
                        $valid['ext'] = true;
                    }   // end if if preg_match 
                } else {
                    $valid['ext'] = true;
                }   // end if if  !empty
            }   // end if $valid nanpa

            //If the extension number is valid or non-existent, continue
            if ( $valid['ext'] ) {
                $valid['all'] = true;
            }   // end if $valid ext
        }   // end if $valid
        return $valid['all'];
    }   // end functon validate_phone_number

Beachten Sie, dass ich dies in einer Klassenbibliothek habe, also den Aufruf "self :: validate_phone_number" von der ersten Funktion / Methode.

Beachten Sie die Zeile 32 der Funktion "validate_phone_number", in der ich Folgendes hinzugefügt habe:

            if ( !$valid['format'] ) {
            return false;
        } else {

um mir die falsche Rückgabe zukommen zu lassen, wenn keine gültige Telefonnummer vorhanden ist.

Ich muss dies noch mit mehr Daten testen, arbeite aber an aktuellen Daten mit dem aktuellen Format und verwende den Stil '8' für diesen bestimmten Datenstapel.

Außerdem habe ich die "Erweiterungs" -Logik auskommentiert, da ich ständig Fehler davon bekam, da ich keine dieser Informationen in meinen Daten habe.


1

Dies dauert 7, 10 und 11 Ziffern, entfernt zusätzliche Zeichen und fügt Bindestriche hinzu, indem Sie durch die Zeichenfolge von rechts nach links gehen. Ändern Sie den Bindestrich in ein Leerzeichen oder einen Punkt.

$raw_phone = preg_replace('/\D/', '', $raw_phone);
$temp = str_split($raw_phone);
$phone_number = "";
for ($x=count($temp)-1;$x>=0;$x--) {
    if ($x === count($temp) - 5 || $x === count($temp) - 8 || $x === count($temp) - 11) {
        $phone_number = "-" . $phone_number;
    }
    $phone_number = $temp[$x] . $phone_number;
}
echo $phone_number;

1

Ich weiß, dass das OP ein 123-456-7890-Format anfordert, aber basierend auf John Duls Antwort habe ich es so geändert, dass die Telefonnummer in Klammern zurückgegeben wird, z. B. (123) 456-7890. Dieser behandelt nur 7- und 10-stellige Zahlen.

function format_phone_string( $raw_number ) {

    // remove everything but numbers
    $raw_number = preg_replace( '/\D/', '', $raw_number );

    // split each number into an array
    $arr_number = str_split($raw_number);

    // add a dummy value to the beginning of the array
    array_unshift( $arr_number, 'dummy' );

    // remove the dummy value so now the array keys start at 1
    unset($arr_number[0]);

    // get the number of numbers in the number
    $num_number = count($arr_number);

    // loop through each number backward starting at the end
    for ( $x = $num_number; $x >= 0; $x-- ) {

        if ( $x === $num_number - 4 ) {
            // before the fourth to last number

            $phone_number = "-" . $phone_number;
        }
        else if ( $x === $num_number - 7 && $num_number > 7 ) {
            // before the seventh to last number
            // and only if the number is more than 7 digits

            $phone_number = ") " . $phone_number;
        }
        else if ( $x === $num_number - 10 ) {
            // before the tenth to last number

            $phone_number = "(" . $phone_number;
        }

        // concatenate each number (possibly with modifications) back on
        $phone_number = $arr_number[$x] . $phone_number;
    }

    return $phone_number;
}

1

Hier ist meine Einstellung:

$phone='+11234567890';
$parts=sscanf($phone,'%2c%3c%3c%4c');
print "$parts[1]-$parts[2]-$parts[3]";

//  123-456-7890

Die sscanfFunktion verwendet als zweiten Parameter eine Formatzeichenfolge, die angibt, wie die Zeichen aus der ersten Zeichenfolge zu interpretieren sind. In diesem Fall bedeutet dies 2 Zeichen ( %2c), 3 Zeichen, 3 Zeichen, 4 Zeichen.

Normalerweise würde die sscanfFunktion auch Variablen enthalten, um die extrahierten Daten zu erfassen. Wenn nicht, werden die Daten in einem Array zurückgegeben, das ich aufgerufen habe $parts.

Die printAnweisung gibt die interpolierte Zeichenfolge aus. $part[0]wird ignoriert.

Ich habe eine ähnliche Funktion verwendet, um australische Telefonnummern zu formatieren.

Beachten Sie, dass aus der Perspektive der Speicherung der Telefonnummer:

  • Telefonnummern sind Zeichenfolgen
  • Gespeicherte Daten sollten keine Formatierungen wie Leerzeichen oder Bindestriche enthalten

Dies ist die eleganteste und lesbarste Lösung. KUSS. Scrollen Sie nicht weiter, wenn Ihre Eingabezeichenfolgen immer genau dem gleichen Muster folgen. Vielen Dank für diesen Zusatz.
Musa vor

1

Telefonformate für Großbritannien

Für die von mir entwickelte Anwendung stellte ich fest, dass die Benutzer ihre Telefonnummer "korrekt" aus einem für Menschen lesbaren Formular eingegeben, aber verschiedene zufällige Zeichen wie "-" / "+44" usw. eingefügt haben. Das Problem war, dass die Cloud-App dies tat Es musste ziemlich genau über das Format gesprochen werden. Anstatt einen regulären Ausdruck zu verwenden (kann für den Benutzer frustrierend sein), habe ich eine Objektklasse erstellt, die die eingegebene Nummer in das richtige Format verarbeitet, bevor sie vom Persistenzmodul verarbeitet wird.

Das Format der Ausgabe stellt sicher, dass jede empfangende Software die Ausgabe als Text und nicht als Ganzzahl interpretiert (die dann sofort die führende Null verlieren würde) und das Format mit British Telecoms übereinstimmt Richtlinien zur Formatierung von Zahlen - dies unterstützt auch die Einprägsamkeit des Menschen, indem eine lange Zahl in kleine, leicht zu merkende Gruppen unterteilt wird.


+441234567890 produziert (01234) 567 890
02012345678 produziert (020) 1234 5678
1923123456 produziert (01923) 123 456
01923123456 produziert (01923) 123 456
01923hello das ist text123456 produziert (01923) 123 456

Die Bedeutung des Vermittlungssegments der Nummer - in Klammern - besteht darin, dass in Großbritannien und den meisten anderen Ländern Anrufe zwischen Nummern in derselben Vermittlungsstelle ohne das Vermittlungssegment getätigt werden können. Dies gilt jedoch nicht für Telefonnummern der Serien 07, 08 und 09.

Ich bin sicher, dass es effizientere Lösungen gibt, aber diese hat sich als äußerst zuverlässig erwiesen. Weitere Formate können problemlos hinzugefügt werden, indem am Ende die teleNum-Funktion hinzugefügt wird.

Die Prozedur wird somit vom aufrufenden Skript aufgerufen

$telephone = New Telephone;
$formattedPhoneNumber = $telephone->toIntegerForm($num)

`

<?php
class   Telephone 
{   
    public function toIntegerForm($num) {
        /*
         * This section takes the number, whatever its format, and purifies it to just digits without any space or other characters
         * This ensures that the formatter only has one type of input to deal with
         */
        $number = str_replace('+44', '0', $num);
        $length = strlen($number);
        $digits = '';
        $i=0;
        while ($i<$length){
            $digits .= $this->first( substr($number,$i,1) , $i);
            $i++;
        }
        if (strlen($number)<10) {return '';}
        return $this->toTextForm($digits);
    }
    public function toTextForm($number) {

        /*
         * This works on the purified number to then format it according to the group code
         * Numbers starting 01 and 07 are grouped 5 3 3
         * Other numbers are grouped 3 4 4 
         * 
         */
        if (substr($number,0,1) == '+') { return $number; }
        $group = substr($number,0,2);
        switch ($group){
            case "02" :
                $formattedNumber = $this->teleNum($number, 3, 4); // If number commences '02N' then output will be (02N) NNNN NNNN
                break;
            default :
                $formattedNumber = $this->teleNum($number, 5, 3); // Otherwise the ooutput will be (0NNNN) NNN NNN
        }
        return $formattedNumber;

    }
    private function first($digit,$position){
        if ($digit == '+' && $position == 0) {return $digit;};
        if (!is_numeric($digit)){
            return '';
        }
        if ($position == 0) {
            return ($digit == '0' ) ? $digit :  '0'.$digit;
        } else {
            return $digit;
        } 
    }
    private function teleNum($number,$a,$b){
        /*
         * Formats the required output 
         */
        $c=strlen($number)-($a+$b);
        $bit1 = substr($number,0,$a);
        $bit2 = substr($number,$a,$b);
        $bit3 = substr($number,$a+$b,$c);
        return '('.$bit1.') '.$bit2." ".$bit3;
    }
}

0

Dies gilt für Festnetzanschlüsse in Großbritannien ohne Ländercode

function format_phone_number($number) {
    $result = preg_replace('~.*(\d{2})[^\d]{0,7}(\d{4})[^\d]{0,7}(\d{4}).*~', '$1 $2 $3', $number);
    return $result;
}

Ergebnis:

2012345678
becomes
20 1234 5678

0

Bitte schauen Sie sich die substr-basierte Funktion an, die Formate ändern kann

function phone(string $in): string
{
    $FORMAT_PHONE = [1,3,3,4];
    $result =[];
    $position = 0;
    foreach ($FORMAT_PHONE as $key => $item){
        $result[] = substr($in, $position, $item);
        $position += $item;
    }
    return '+'.implode('-',$result);
}

0

Überprüfen Sie die Telefonnummer

$phone = '+385 99 1234 1234'

$str = preg_match('/^\+?\d{1,3}[\s-]?\d{1,3}[\s-]?\d{1,4}[\s-]?\d{1,4}$/', $phone);

if($str){
return true;
}else{
return false;
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.