﻿# 使用 Regular Expression 驗證密碼複雜度

以前我都沒想過可以用 Regular Expressions 驗證複雜格式的密碼，原來可以用 Regular Expression 中的[群組建構](http://msdn.microsoft.com/zh-tw/library/bs2twtah.aspx)式達成這個目的，例如說密碼的條件是這樣： 

1.  至少有一個數字
2.  至少有一個小寫英文字母
3.  至少有一個大寫英文字母
4.  字串長度在 6 ~ 30 個字母之間

那麼你的 Regular Expression 可以長這樣：

```
^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,30}$
```

在這段 Regular Expression 的語法中值得注意的就是 **(?=.\*\\d)** 這段語法，這段於法又稱做「右合樣 (Positive Lookahead)」，右合樣（或左合樣）語法所佔用的寬度為 0，也就是說這段語法本真不會佔用比對的字元，僅僅只是 Regular Expression 中的一種「判斷式」而已，右合樣 (Positive Lookahead)會判斷右邊緊接著的字元是否符合比對條件，如果符合條件才會繼續比對下去。

所以剛剛這段於法的解釋大致可以這樣說明：

(?=.\*\\d) 與 (?=.\*\[a-z\]) 與 (?=.\*\[A-Z\]) 寬度都會是零，所以整個字串比對會以 .{6,30} 為主，但比對之前會分別比對 (?=.\*\\d) 與 (?=.\*\[a-z\]) 與 (?=.\*\[A-Z\]) 這三個判斷式，都判斷成功才會進行 .{6,30} 的比對。所以 (?=.\*\\d) 的 .\*\\d 就是說右邊的文字中一定要出現一個數字符號，(?=.\*\[a-z\]) 的 .\*\[a-z\] 就是說右邊的文字中一定要出現一個小寫字母，(?=.\*\[A-Z\]) 的 .\*\[A-Z\] 就是說右邊的文字中一定要出現一個大小字母，最後才會比對 .{6,30} 也就是說比對字串的長度必須在 6 ~ 30 個字的任意字元。

如果你的條件修改成：

1.  至少有一個數字
2.  至少有一個大寫或小寫英文字母
3.  至少有一個特殊符號
4.  字串長度在 6 ~ 30 個字母之間

那麼你的 Regular Expression 可以長這樣（以 C# 作範例）：

```
Regex regex = new Regex(@"^(?=.*\d)(?=.*[a-zA-Z])(?=.*\W).{6,30}$");
```

這樣一來你知道如何融會貫通了嗎？^\_^

**相關連結**

-   [整理一些 Regex 的學習資源](/post/2008/03/23/Regular-Expression-Regex-Learning-Resources)
-   [非回溯的向右合樣和向左合樣](http://msdn.microsoft.com/zh-tw/library/e902768h.aspx)
-   [群組建構](http://msdn.microsoft.com/zh-tw/library/bs2twtah.aspx)
    -   [零寬度右合樣 (Positive Lookahead) 判斷提示](https://learn.microsoft.com/zh-tw/previous-versions/dotnet/netframework-4.0/bs2twtah\(v=vs.100\)?redirectedfrom=MSDN#%E9%9B%B6%E5%AF%AC%E5%BA%A6%E5%8F%B3%E5%90%88%E6%A8%A3-positive-lookahead-%E5%88%A4%E6%96%B7%E6%8F%90%E7%A4%BA)
    -   [零寬度右不合樣 (Negative Lookahead) 判斷提示](https://learn.microsoft.com/zh-tw/previous-versions/dotnet/netframework-4.0/bs2twtah\(v=vs.100\)?redirectedfrom=MSDN#%E9%9B%B6%E5%AF%AC%E5%BA%A6%E5%8F%B3%E4%B8%8D%E5%90%88%E6%A8%A3-negative-lookahead-%E5%88%A4%E6%96%B7%E6%8F%90%E7%A4%BA)
    -   [零寬度左合樣 (Positive Lookbehind) 判斷提示](https://learn.microsoft.com/zh-tw/previous-versions/dotnet/netframework-4.0/bs2twtah\(v=vs.100\)?redirectedfrom=MSDN#%E9%9B%B6%E5%AF%AC%E5%BA%A6%E5%B7%A6%E5%90%88%E6%A8%A3-positive-lookbehind-%E5%88%A4%E6%96%B7%E6%8F%90%E7%A4%BA)
    -   [零寬度左不合樣 (Negative Lookbehind) 判斷提示](https://learn.microsoft.com/zh-tw/previous-versions/dotnet/netframework-4.0/bs2twtah\(v=vs.100\)?redirectedfrom=MSDN#%E9%9B%B6%E5%AF%AC%E5%BA%A6%E5%B7%A6%E4%B8%8D%E5%90%88%E6%A8%A3-negative-lookbehind-%E5%88%A4%E6%96%B7%E6%8F%90%E7%A4%BA)
    -   [非回溯子運算式](https://learn.microsoft.com/zh-tw/previous-versions/dotnet/netframework-4.0/bs2twtah\(v=vs.100\)?redirectedfrom=MSDN#%E9%9D%9E%E5%9B%9E%E6%BA%AF%E5%AD%90%E9%81%8B%E7%AE%97%E5%BC%8F)
