郵箱正則表達(dá)式+正則基本知識(shí)點(diǎn)

掌握正則表達(dá)式,是開發(fā)工程師的基本功,因此首先要掌握正則表達(dá)式的基本知識(shí)點(diǎn)!

一般程序員的姿勢(shì)

  1. 每次需要用正則表達(dá)式,就到網(wǎng)上copy一份,根本沒弄懂copy的正則表達(dá)式具體含義;
  2. 同一個(gè)項(xiàng)目中,多處用到同一種正則校驗(yàn),每次都是復(fù)制粘貼一份,萬一哪天領(lǐng)導(dǎo)說業(yè)務(wù)變動(dòng),正則表達(dá)式得調(diào)整,該起來相當(dāng)麻煩;

正則表達(dá)式正確的運(yùn)用姿勢(shì)

  1. 徹底理解正則表達(dá)式的基本原理/知識(shí)點(diǎn),即便是copy過來的正則表達(dá)式也得搞清楚為什么這么寫;
  2. 同一個(gè)項(xiàng)目當(dāng)中,同一種正則表達(dá)式,只能寫一遍,需要用到的地方直接引用,后期維護(hù)才能事半功倍!

今天來搞幾個(gè)郵箱正則表達(dá)式,匹配多級(jí)域名,包括中文域名

阿里云域名注冊(cè)截圖

從上圖可以得出,除去“.”號(hào),域名既有英文(最多是6個(gè)字符),也有中文(最多是3個(gè)漢字)
而現(xiàn)在有很多影子郵箱/百變郵箱,是使用二級(jí)域名或者三級(jí)域名,所以,我們先列舉如下幾個(gè)郵箱,然后寫一個(gè)正則表達(dá)式,去匹配、判斷

  mail_666@qq.com
  mail_666@jack.uu.com
  mail_666@jack.uu.com.cn
  mail_666@qq.中文網(wǎng)
  mail_666@jack.uu.中文網(wǎng)
  mail_666@jack.uu.我愛你

思路

不管是什么郵箱,確定會(huì)有的字符是“@”和至少一個(gè)“.”(這里特指最后一個(gè)),那么我們就以這兩個(gè)確定的符號(hào)為分界點(diǎn),將每個(gè)郵箱拆分成3段,對(duì)每一段進(jìn)行正則匹配,最終組成整個(gè)郵箱的正則匹配。當(dāng)然進(jìn)入下一步之前,先理一理基本知識(shí)點(diǎn)。

正則表達(dá)式基本知識(shí)點(diǎn)

一、橫向模糊匹配(匹配字符串出現(xiàn)的長(zhǎng)度)

定義:一個(gè)正則可以匹配的字符串的長(zhǎng)度不是固定的,使用量詞可以達(dá)到這種目的。

量詞:比如{m , n} :表示連續(xù)出現(xiàn)最少 m 次,最多 n 次;跟在一個(gè)字符的后面就表示對(duì)該字符的限定。

比如郵箱的校驗(yàn):/^\w+@[a-z0-9]+.[a-z]{2,4}$/,寫在了[a-z]后面,表示可以有2到4位的字母

又比如手機(jī)號(hào)的校驗(yàn): /^1[3456789]\d{9}$/,跟在了\d后面,表示需要出現(xiàn)9個(gè)數(shù)字

對(duì)于量詞的總結(jié):

{m , n}  :表示連續(xù)出現(xiàn)最少 m 次,最多 n 次
{m , }   :表示至少出現(xiàn)m次
{m}      :表示出現(xiàn)m次
?      :等價(jià)于{0,1} 表示出現(xiàn)或不出現(xiàn)
+        :等價(jià)于{1,} 表示至少出現(xiàn)1次
*        :等價(jià)于{0,} 表示出現(xiàn)任意次,可以不出現(xiàn)

二、縱向模糊匹配(匹配可能出現(xiàn)哪些字符)

定義:正則匹配的字符串對(duì)于某一位置上的字符來說,它可以有多種可能,不局限于某一類型,使用字符組可以達(dá)到這種目的。

字符組:比如[abc],表示該字符是可以字符 "a"、"b"、"c" 中的任何一個(gè)。對(duì)于這一位置來說,我們可以有3種可能性。

比如手機(jī)號(hào)的校驗(yàn): /^1[3456789]\d{9}$/,它在第二個(gè)位置,根據(jù)一般手機(jī)運(yùn)營(yíng)商來說,提供手機(jī)第二位的數(shù)字可以是3到9的任意一個(gè),才符合規(guī)范。

如果字符組里表示的字符特別多,可以使用范圍表示法,用連字符-來省略和縮寫。

比如郵箱的校驗(yàn):/^\w+@[a-z0-9]+.[a-z]{2,4}$/,它跟在@后面,根據(jù)我們郵箱的規(guī)范可知,@后面的[a-z0-9]+表示:數(shù)字0到9和字母a-z中的至少一個(gè)字符

三、常用的簡(jiǎn)寫形式

\d  :表示[0-9],表示一位數(shù)字
\D  :表示[^0-9],表示除數(shù)字外的任意字符
\w  :表示[0-9a-zA-Z_],表示數(shù)字、大小寫字母和下劃線
\W  :表示[^0-9a-zA-Z_],非單詞字符
\b  :表示匹配一個(gè)單詞邊界,也就是指單詞和空格間的位置。例如,“er\b”可以匹配“never”中的“er”,但不能匹配“verb”中的“er”
\B  :匹配非單詞邊界?!癳r\B”能匹配“verb”中的“er”,但不能匹配“never”中的“er”。
\s  :匹配任何空白字符,包括空格、制表符、換頁符等等。等價(jià)于[ \f\n\r\t\v]。
\S  :匹配任何非空白字符。等價(jià)于[^ \f\n\r\t\v]。

先上結(jié)論

js正則驗(yàn)證郵箱:/^\w+@[\da-z\.-]+\.([a-z]{2,6}|[\u2E80-\u9FFF]{2,3})$/
php正則驗(yàn)證郵箱:/^\w+@([\da-z\.-]+)\.([a-z]{2,6}|[\x7f-\xff]{6,9})/

這里簡(jiǎn)單解析一下:

  1. 第一段:@符號(hào)之前,其實(shí)就是郵箱的用戶名,現(xiàn)在一般郵箱的用戶名是字母、數(shù)字和下劃線組成的,用"\w",剛好
  2. 第二段:@符號(hào)之后最后一個(gè)“.”之前,“([\da-z.-]+)”,不管是js還是php,都是一樣的,匹配多個(gè)包含數(shù)字、小寫字母、“.”和“-”的字符串
  3. 第三段:最后一個(gè)“.”之后的部分:

對(duì)于js正則:([a-z]{2,6}|[\u2E80-\u9FFF]{2,3})

[a-z]{2,6}:匹配2~6個(gè)小寫字母
[\u2E80-\u9FFF]{2,3}:匹配2~3個(gè)中文漢字

js正則的中文漢字正則表達(dá)式來源于手冊(cè):https://tool.oschina.net/uploads/apidocs/jquery/regexp.html

對(duì)于php正則:([a-z]{2,6}|[\x7f-\xff]{6,9})

[a-z]{2,6}:匹配2~6個(gè)小寫字母
[\x7f-\xff]{6,9}:匹配2~3個(gè)中文漢字,在utf-8編碼中,3個(gè)字符為1個(gè)漢字

在utf-8編碼中,用ASCII碼表中的第128~255編碼中的3個(gè)編碼表示一個(gè)漢字,這里用十六進(jìn)制表示

驗(yàn)證一下:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>正則表達(dá)式測(cè)試</title>
</head>
<body>

<script type="text/javascript" charset="utf-8">
  //下面這個(gè)是匹配中文域名郵箱的
  var patt1=new RegExp(/^\w+@([\da-z\.-]+)\.([a-z]{2,6}|[\u2E80-\u9FFF]{2,3})$/);
  // var patt1=new RegExp(/^\w+@([\da-z\.-]+)\.([a-z]+|[\u2E80-\u9FFF]+)$/);
  document.write(patt1.test("mail_666@qq.com")+" | ");
  document.write(patt1.test("mail_666@jack.uu.com")+" | ");
  document.write(patt1.test("mail_666@jack.uu.com.cn")+" | ");
  document.write(patt1.test("mail_666@qq.中文網(wǎng)")+" | ");
  document.write(patt1.test("mail_666@jack.uu.中文網(wǎng)")+" | ");
  document.write(patt1.test("mail_666@jack.uu.我愛你")+" | ");
</script>

</body>
</html>

運(yùn)行結(jié)果:

true | true | true | true | true | true |
<?php
/**
 * Create by PhpStorm
 * User : Actor
 * Date : 2021-06-25
 * Time : 10:27
 */
//臨時(shí)啟用全局錯(cuò)誤提示
ini_set('display_errors', true);
error_reporting(E_ALL);
$rowBreak = (PHP_SAPI == 'cli') ? "\n" : '<br>';
$mailArr = [
    'mail_666@qq.com',
    'mail_666@jack.uu.com',
    'mail_666@jack.uu.com.cn',
    'mail_666@qq.中文網(wǎng)',
    'mail_666@jack.uu.中文網(wǎng)',
    'mail_666@jack.uu.我愛你',
];

$patternArr = [
    '/^\w+@([\da-z\.-]+)\.([a-z]{2,6}|[\x7f-\xff]{6,9})/',
    //'/^\w+@([\da-z\.-]+)\.([a-z\x7f-\xff]+)/',
    //'/^\w+@([\da-z\.-]+)\.([a-z]{2,6}|[\x{4e00}-\x{9fa5}]{2,3})$/u',
    //'/^\w+@([\da-z\.-]+)\.([a-z\x{4e00}-\x{9fa5}]+)$/u',
];
echo "<pre>";
foreach($patternArr as $pattern) {
    foreach ($mailArr as $mail) {
        echo "Pattern: {$pattern} {$rowBreak}";
        var_dump(testRegExpMatch($pattern, $mail));
        echo $rowBreak;
    }
}
echo "</pre>";
/**
 * 測(cè)試正則匹配
 * @param  string $pattern 正則表達(dá)式
 * @param  string $string  源字符串
 * @return array
 */
function testRegExpMatch($pattern, $string) {
    try {
        preg_match($pattern, $string, $matches);
    } catch (Exception $e) {
        return array(
            'stauts' => false,
            'msg'    => $e->getMessage(),
            'matches' => array(),
        );
    }
    return array(
        'stauts'     => true,
        'msg'        => 'Success',
        'matches'    => $matches,
    );
}

運(yùn)行結(jié)果

Pattern: /^\w+@([\da-z\.-]+)\.([a-z]{2,6}|[\x7f-\xff]{6,9})/ 
array(3) {
  ["stauts"]=>
  bool(true)
  ["msg"]=>
  string(7) "Success"
  ["matches"]=>
  array(3) {
    [0]=>
    string(15) "mail_666@qq.com"
    [1]=>
    string(2) "qq"
    [2]=>
    string(3) "com"
  }
}

Pattern: /^\w+@([\da-z\.-]+)\.([a-z]{2,6}|[\x7f-\xff]{6,9})/ 
array(3) {
  ["stauts"]=>
  bool(true)
  ["msg"]=>
  string(7) "Success"
  ["matches"]=>
  array(3) {
    [0]=>
    string(20) "mail_666@jack.uu.com"
    [1]=>
    string(7) "jack.uu"
    [2]=>
    string(3) "com"
  }
}

Pattern: /^\w+@([\da-z\.-]+)\.([a-z]{2,6}|[\x7f-\xff]{6,9})/ 
array(3) {
  ["stauts"]=>
  bool(true)
  ["msg"]=>
  string(7) "Success"
  ["matches"]=>
  array(3) {
    [0]=>
    string(23) "mail_666@jack.uu.com.cn"
    [1]=>
    string(11) "jack.uu.com"
    [2]=>
    string(2) "cn"
  }
}

Pattern: /^\w+@([\da-z\.-]+)\.([a-z]{2,6}|[\x7f-\xff]{6,9})/ 
array(3) {
  ["stauts"]=>
  bool(true)
  ["msg"]=>
  string(7) "Success"
  ["matches"]=>
  array(3) {
    [0]=>
    string(21) "mail_666@qq.中文網(wǎng)"
    [1]=>
    string(2) "qq"
    [2]=>
    string(9) "中文網(wǎng)"
  }
}

Pattern: /^\w+@([\da-z\.-]+)\.([a-z]{2,6}|[\x7f-\xff]{6,9})/ 
array(3) {
  ["stauts"]=>
  bool(true)
  ["msg"]=>
  string(7) "Success"
  ["matches"]=>
  array(3) {
    [0]=>
    string(26) "mail_666@jack.uu.中文網(wǎng)"
    [1]=>
    string(7) "jack.uu"
    [2]=>
    string(9) "中文網(wǎng)"
  }
}

Pattern: /^\w+@([\da-z\.-]+)\.([a-z]{2,6}|[\x7f-\xff]{6,9})/ 
array(3) {
  ["stauts"]=>
  bool(true)
  ["msg"]=>
  string(7) "Success"
  ["matches"]=>
  array(3) {
    [0]=>
    string(26) "mail_666@jack.uu.我愛你"
    [1]=>
    string(7) "jack.uu"
    [2]=>
    string(9) "我愛你"
  }
}

全部通過

當(dāng)然,php正則匹配郵箱,還可以這樣子

/^\w+@([\da-z\.-]+)\.([a-z]{2,6}|[\x{4e00}-\x{9fa5}]{2,3})$/u

原理與/^\w+@([\da-z\.-]+)\.([a-z]{2,6}|[\x7f-\xff]{6,9})/類似。

最后,上面的幾個(gè)正則表達(dá)式是居于當(dāng)前市面上現(xiàn)存的域名進(jìn)行匹配的,下面提供幾個(gè)更加寬松的郵箱正則匹配

js正則匹配郵箱(寬松匹配):/^\w+@([\da-z\.-]+)\.([a-z]+|[\u2E80-\u9FFF]+)$/
php正則匹配郵箱(寬松匹配):/^\w+@([\da-z\.-]+)\.([a-z\x7f-\xff]+)/
php正則匹配郵箱(寬松匹配):/^\w+@([\da-z\.-]+)\.([a-z\x{4e00}-\x{9fa5}]+)$/u

原理都相似,可以對(duì)照理解下。如有誤,歡迎留言區(qū)批評(píng)指正。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容