测试正则表达式并在不适合时更改文本的函数


A function to test a regular expression and change the text if it does not fit

我试图使用if语句来确定PHP中的某个变量($phone)是否匹配正则表达式。有三种不同的选项-它要么正确传递它,它是一个基本正确的值,只需要一些轻微的修改,最后,它是一个错误的值,应该返回到上一页的错误消息。以下是我目前得到的:

编辑:$phone的期望值为123-456-7890、1234567890或(123)456-7890。数据库所需的输入是123-456-7890

if (preg_match("/^'d{3}-'d{3}-'d{4}$/", $phone)) {
    // This is the 100% correct version
}
else if (preg_match("/^'d{10}$/", $phone)) {
    $phone = preg_replace("/^(.{3})/", "-", $phone);
    $phone = preg_replace("/^(.{6})/", "-", $phone);
// This is one of the mostly correct - this does not seem to work. I got a value of -37 when I tried to use it
}
else if (preg_match("/^'('d{3}') 'd{3}-'d{4}$/", $phone)) {
    // Have not tried anything here, because the problems here are similar to the else if statement above
}
else {
    header('Location: '.$admin.'?error=phone');
// This should direct back to the previous page with an error message.
}

编辑2:好吧,我已经得到了if和else if的工作,但是else不重定向回页面或防止插入到数据库中。我该怎么做呢?

如何:

$phone = preg_replace("/^('d{3})('d{3})/", "$1-$2-", $phone);

第二个

$phone = preg_replace("/^'(('d{3})') /", "$1-", $phone);

解释:

/         : regex delimiter
^         : start of the string
('d{3})   : group 1 capture 3 digits
('d{3})   : group 2 capture 3 next digits
/

更换部件:

$1        : value captured in group 1 (the first 3 digits)
-         : a dash
$2        : value captured in group 2 (the next 3 digits)
-         : a dash

对于处理所有的测试用例,我会这样做:

// Remove all non digit
$phone = preg_replace('/'D+/', '', $phone);
// then we must have a 10 digit number
if (preg_match('/^'d{10}$/', $phone) {
    $phone = preg_replace("/^('d{3})('d{3})/", "$1-$2-", $phone);
} else {
    // error
}

只需在一个regex中完成所有操作,使用像这样的regex和preg_replace。

'(?('d{3})[)-]?'s?('d{3})-?('d{4})

正则表达式的解释(很可能可以改进):

'(? // Optionally match the left parenthesis
('d{3}) // Match 3 digits, capture those digits into backreference #1
[)-]?   // Optionally match one of the characters: right parenthesis or dash
's?     // Optionally match a space
('d{3}) // Match 3 digits, capture those digits into backreference #2
-?      // Optionally match the dash
('d{4}) // Match 4 digits, capture those digits into backreference #3

和替换的解释:

$1-$2-$3

这意味着从上面的反向引用中获取值,并将它们放在字符串中,每个值用破折号分隔。

查看演示,看看它是否通过了所有的测试用例。

Edit:要检测无效格式,只需检查以确保从替换中返回的是有效格式,如下所示:

$replace = preg_replace( '#'(?('d{3})[)-]?'s?('d{3})-?('d{4})#i', '$1-$2-$3', $test);
if( !preg_match('/'d{3}-'d{3}-'d{4}/', $replace))
{
    // Redirect
}

您可以尝试这样做:

$phone = '(555) 555-5555';
//ONLY CHECK IF IT DOESNT MATCH
if ( !preg_match( '/^'d{3}-'d{3}-'d{4}$/', $phone ) )
{
  //CHECK FOR SOLID 10 NUMBERS
  if( preg_match( '/^'d{10}$/', $phone ) )
  {
    preg_match( '/^('d{3})('d{3})('d{4})$/', $phone, $matches );
    $phone = $matches[1].'-'.$matches[2].'-'.$matches[3];
  }
  //CHECK FOR BRACKET/DASH VERSION
  elseif( preg_match( '/^'('d{3}')' 'd{3}-'d{4}$/', $phone ) )
  {
    preg_match( '/^'(('d{3})') ('d{3})-('d{4})$/i', $phone, $matches );
    $phone = $matches[1].'-'.$matches[2].'-'.$matches[3];
  }
  else
  {
    header('Location: '.$admin.'?error=phone');
  }
}
echo $phone;

更小的版本是:

//ONLY CHECK IF IT DOESNT MATCH
if ( !preg_match( '/^'d{3}-'d{3}-'d{4}$/', $phone ) )
{
  if( preg_match( '/^(?:'(('d{3})') ('d{3})-('d{4}))|(?:('d{3})('d{3})('d{4}))$/', $phone, $matches ) )
  {
    if( !empty( $matches[1] ) )
    {
      $phone = $matches[1].'-'.$matches[2].'-'.$matches[3];
    }
    else
    {
      $phone = $matches[4].'-'.$matches[5].'-'.$matches[6];
    }
  }
  else
  {
    header('Location: '.$admin.'?error=phone');
  }
}

下面是一个经过测试的函数:

// Return tidied up 10 digit US phone number or FALSE if invalid.
function validateAndTidyPhoneNumber($text) {
    $re = '/ # Match loosely formatted US phone number.
        ^           # Anchor to start of string.
        's*         # Allow leading whitespace.
        '(?         # First digit set may be inside ().
        ([0-9]{3})  # $1: 3 digits (1st set).
        ')?         # First digit set may be inside ().
        [ -]*       # Allow space or dash separators.
        ([0-9]{3})  # $2: 3 digits (2nd set).
        [ -]*       # Allow space or dash separators.
        ([0-9]{4})  # $3: 4 digits (3rd set).
        's*         # Allow trailing whitespace.
        $           # Anchor to end of string.
        /ix';
    // Tidy up phone number.
    $text = preg_replace($re, '$1-$2-$3', $text);
    // Return tidied-up phone number if in correct format.
    if (preg_match('/^[0-9]{3}-[0-9]{3}-[0-9]{4}$/', $text)) {
        return $text;
    }
    return FALSE; // Otherwise bad phone number.
}