Validator.js 很好用的客戶端表單驗證

   1:   /*************************************************
   2:      Validator v1.05
   3:      code by 我佛山人
   4:      [email protected]
   5:  *************************************************/
   6:   Validator = {
   7:      Require : /.+/,
   8:      Email : /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/,
   9:      Phone : /^((\(\d{2,3}\))|(\d{3}\-))?(\(0\d{2,3}\)|0\d{2,3}-)?[1-9]\d{6,7}(\-\d{1,4})?$/,
  10:      Mobile : /^((\(\d{2,3}\))|(\d{3}\-))?13\d{9}$/,
  11:      Url : /^http:\/\/[A-Za-z0-9]+\.[A-Za-z0-9]+[\/=\?%\-&_~`@[\]\':+!]*([^<>\"\"])*$/,accept'))",min'),  getAttribute('max'))",min'), getAttribute('max'))",min'), getAttribute('format'))",to'))[0].value",min') < (value|0) && (value|0) < getAttribute('max')",operator'),getAttribute('to'))",regexp'))",name'), getAttribute('min'), getAttribute('max'))",','','','','','','','','','','','北京','天津','河北','山西','內蒙古','','','','','','遼寧','吉林','黑龍江','','','','','','','','上海','江蘇','浙江','安微','福建','江西','山東','','','','河南','湖北','湖南','廣東','廣西','海南','','','','重慶','四川','貴州','雲南','西藏','','','','','','','陝西','甘肅','青海','寧夏','***','','','','','','臺灣','','','','','','','','','','香港','澳門','','','','','','','','','國外'];
  12:      IdCard : "this.IsIdCard(value)",
  13:      Currency : /^\d+(\.\d+)?$/,
  14:      Number : /^\d+$/,
  15:      Zip : /^[1-9]\d{5}$/,
  16:      QQ : /^[1-9]\d{4,8}$/,
  17:      Integer : /^[-\+]?\d+$/,
  18:      Double : /^[-\+]?\d+(\.\d+)?$/,
  19:      English : /^[A-Za-z]+$/,
  20:      Chinese :  /^[\u0391-\uFFE5]+$/,
  21:      Username : /^[a-z]\w{3,}$/i,
  22:      UnSafe : /^(([A-Z]*|[a-z]*|\d*|[-_\~!@#\$%\^&\*\.\(\)\[\]\{\}<>\?\\\/\'\"]*)|.{0,5})$|\s/,
  23:      IsSafe : function(str){return !this.UnSafe.test(str);},
  24:      SafeString : "this.IsSafe(value)",
  25:      Filter : "this.DoFilter(value, getAttribute('
  26:      Limit : "this.limit(value.length,getAttribute('
  27:      LimitB : "this.limit(this.LenB(value), getAttribute('
  28:      Date : "this.IsDate(value, getAttribute('
  29:      Repeat : "value == document.getElementsByName(getAttribute('
  30:      Range : "getAttribute('
  31:      Compare : "this.compare(value,getAttribute('
  32:      Custom : "this.Exec(value, getAttribute('
  33:      Group : "this.MustChecked(getAttribute('
  34:      ErrorItem : [document.forms[0]],
  35:      ErrorMessage : ["以下原因導致提交失敗:\t\t\t\t"],
  36:      Validate : function(theForm, mode){
  37:          var obj = theForm || event.srcElement;
  38:          var count = obj.elements.length;
  39:          this.ErrorMessage.length = 1;
  40:          this.ErrorItem.length = 1;
  41:          this.ErrorItem[0] = obj;
  42:          for(var i=0;i<count;i++){
  43:              with(obj.elements[i]){
  44:                  var _dataType = getAttribute("dataType");
  45:                  if(typeof(_dataType) == "object" || typeof(this[_dataType]) == "undefined")  continue;
  46:                  this.ClearState(obj.elements[i]);
  47:                  if(getAttribute("require") == "false" && value == "") continue;
  48:                  switch(_dataType){
  49:                      case "IdCard" :
  50:                      case "Date" :
  51:                      case "Repeat" :
  52:                      case "Range" :
  53:                      case "Compare" :
  54:                      case "Custom" :
  55:                      case "Group" : 
  56:                      case "Limit" :
  57:                      case "LimitB" :
  58:                      case "SafeString" :
  59:                      case "Filter" :
  60:                          if(!eval(this[_dataType]))    {
  61:                              this.AddError(i, getAttribute("msg"));
  62:                          }
  63:                          break;
  64:                      default :
  65:                          if(!this[_dataType].test(value)){
  66:                              this.AddError(i, getAttribute("msg"));
  67:                          }
  68:                          break;
  69:                  }
  70:              }
  71:          }
  72:          if(this.ErrorMessage.length > 1){
  73:              mode = mode || 1;
  74:              var errCount = this.ErrorItem.length;
  75:              switch(mode){
  76:              case 2 :
  77:                  for(var i=1;i<errCount;i++)
  78:                      this.ErrorItem[i].style.color = "red";
  79:              case 1 :
  80:                  alert(this.ErrorMessage.join("\n"));
  81:                  this.ErrorItem[1].focus();
  82:                  break;
  83:              case 3 :
  84:                  for(var i=1;i<errCount;i++){
  85:                  try{
  86:                      var span = document.createElement("SPAN");
  87:                      span.id = "__ErrorMessagePanel";
  88:                      span.style.color = "red";
  89:                      this.ErrorItem[i].parentNode.appendChild(span);
  90:                      span.innerHTML = this.ErrorMessage[i].replace(/\d+:/,"*");
  91:                      }
  92:                      catch(e){alert(e.description);}
  93:                  }
  94:                  this.ErrorItem[1].focus();
  95:                  break;
  96:              default :
  97:                  alert(this.ErrorMessage.join("\n"));
  98:                  break;
  99:              }
 100:              return false;
 101:          }
 102:          return true;
 103:      },
 104:      limit : function(len,min, max){
 105:          min = min || 0;
 106:          max = max || Number.MAX_VALUE;
 107:          return min <= len && len <= max;
 108:      },
 109:      LenB : function(str){
 110:          return str.replace(/[^\x00-\xff]/g,"**").length;
 111:      },
 112:      ClearState : function(elem){
 113:          with(elem){
 114:              if(style.color == "red")
 115:                  style.color = "";
 116:              var lastNode = parentNode.childNodes[parentNode.childNodes.length-1];
 117:              if(lastNode.id == "__ErrorMessagePanel")
 118:                  parentNode.removeChild(lastNode);
 119:          }
 120:      },
 121:      AddError : function(index, str){
 122:          this.ErrorItem[this.ErrorItem.length] = this.ErrorItem[0].elements[index];
 123:          this.ErrorMessage[this.ErrorMessage.length] = this.ErrorMessage.length + ":" + str;
 124:      },
 125:      Exec : function(op, reg){
 126:          return new RegExp(reg,"g").test(op);
 127:      },
 128:      compare : function(op1,operator,op2){
 129:          switch (operator) {
 130:              case "NotEqual":
 131:                  return (op1 != op2);
 132:              case "GreaterThan":
 133:                  return (op1 > op2);
 134:              case "GreaterThanEqual":
 135:                  return (op1 >= op2);
 136:              case "LessThan":
 137:                  return (op1 < op2);
 138:              case "LessThanEqual":
 139:                  return (op1 <= op2);
 140:              default:
 141:                  return (op1 == op2);            
 142:          }
 143:      },
 144:      MustChecked : function(name, min, max){
 145:          var groups = document.getElementsByName(name);
 146:          var hasChecked = 0;
 147:          min = min || 1;
 148:          max = max || groups.length;
 149:          for(var i=groups.length-1;i>=0;i--)
 150:              if(groups[i].checked) hasChecked++;
 151:          return min <= hasChecked && hasChecked <= max;
 152:      },
 153:      DoFilter : function(input, filter){
 154:  return new RegExp("^.+\.(?=EXT)(EXT)$".replace(/EXT/g, filter.split(/\s*,\s*/).join("|")), "gi").test(input);
 155:      },
 156:      IsIdCard : function(number){
 157:          var date, Ai;
 158:          var verify = "10x98765432";
 159:          var Wi = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
 160:          var area = ['
 161:          var re = number.match(/^(\d{2})\d{4}(((\d{2})(\d{2})(\d{2})(\d{3}))|((\d{4})(\d{2})(\d{2})(\d{3}[x\d])))$/i);
 162:          if(re == null) return false;
 163:          if(re[1] >= area.length || area[re[1]] == "") return false;
 164:          if(re[2].length == 12){
 165:              Ai = number.substr(0, 17);
 166:              date = [re[9], re[10], re[11]].join("-");
 167:          }
 168:          else{
 169:              Ai = number.substr(0, 6) + "19" + number.substr(6);
 170:              date = ["19" + re[4], re[5], re[6]].join("-");
 171:          }
 172:          if(!this.IsDate(date, "ymd")) return false;
 173:          var sum = 0;
 174:          for(var i = 0;i<=16;i++){
 175:              sum += Ai.charAt(i) * Wi[i];
 176:          }
 177:          Ai +=  verify.charAt(sum%11);
 178:          return (number.length ==15 || number.length == 18 && number == Ai);
 179:      },
 180:      IsDate : function(op, formatString){
 181:          formatString = formatString || "ymd";
 182:          var m, year, month, day;
 183:          switch(formatString){
 184:              case "ymd" :
 185:                  m = op.match(new RegExp("^((\\d{4})|(\\d{2}))([-./])(\\d{1,2})\\4(\\d{1,2})$"));
 186:                  if(m == null ) return false;
 187:                  day = m[6];
 188:                  month = m[5]*1;
 189:                  year =  (m[2].length == 4) ? m[2] : GetFullYear(parseInt(m[3], 10));
 190:                  break;
 191:              case "dmy" :
 192:                  m = op.match(new RegExp("^(\\d{1,2})([-./])(\\d{1,2})\\2((\\d{4})|(\\d{2}))$"));
 193:                  if(m == null ) return false;
 194:                  day = m[1];
 195:                  month = m[3]*1;
 196:                  year = (m[5].length == 4) ? m[5] : GetFullYear(parseInt(m[6], 10));
 197:                  break;
 198:              default :
 199:                  break;
 200:          }
 201:          if(!parseInt(month)) return false;
 202:          month = month==0 ?12:month;
 203:          var date = new Date(year, month-1, day);
 204:          return (typeof(date) == "object" && year == date.getFullYear() && month == (date.getMonth()+1) && day == date.getDate());
 205:          function GetFullYear(y){return ((y<30 ? "20" : "19") + y)|0;}
 206:      }
 207:   }

 

使用:

 

語法dataType="Require | Chinese | English | Number | Integer | Double | Email | Url | Phone | Mobile | Currency | Zip | IdCard | QQ | Date | SafeString | Repeat | Compare | Range | Limit | LimitB | Group | Custom"
類型字符串。必選。
說明:用於設定表單項的輸入數據驗證類型。
選值說明
可選值 驗證功能
Require 必填項
Chinese 中文
English 英文

Number
數字
Integer
整數
Double
實數
Email
Email地址格式
Url
基於HTTP協議的網址格式
Phone
電話號碼格式
Mobile
手機號碼格式
Currency
貨幣格式
Zip
郵政編碼
IdCard
身份證號碼
QQ
QQ號碼
Date
日期
SafeString
安全密碼
Repeat
重複輸入
Compare
關係比較
Range
輸入範圍
Limit
限制輸入長度
LimitB
限制輸入的字節長度
Group 驗證單/多選按鈕組
Custom 自定義正則表達式驗證

 

 

語法max="int"
類型:字符串。在dataType屬性值爲Range時必選,爲Group且待驗證項是多選按鈕組時可選(此時默認值爲1),爲爲Limit/LimitB時可選(此時默認值爲1.7976931348623157e+308,即Number.MAX_VALUE的值)。
說明:當daType屬性值爲Range時,用於判斷輸入是否在minmax的屬性值間;當dataType屬性值爲Group,且待驗證項是多選按鈕組時,用於設定多選按鈕組的選中個數,判斷選中個數是否在[min, max]區間;當daType屬性值爲Limit時,用於驗證輸入的字符數是否在[min, max]區間;當daType屬性值爲LimitB時,用於驗證輸入字符的字節數是否在[min, max]區間。

 

 

語法min="int"
類型:字符串。在dataType屬性值爲Range時必選,爲Group且待驗證項是多選按鈕組時可選(此時默認值爲1),爲爲Limit/LimitB時可選(此時默認值爲0)。
說明:當daType屬性值爲Range時,用於判斷輸入是否在minmax的屬性值間;當dataType屬性值爲Group,且待驗證項是多選按鈕組時,用於設定多選按鈕組的選中個數,判斷選中個數是否在[min, max]區間;當daType屬性值爲Limit時,用於驗證輸入的字符數是否在[min, max]區間;當daType屬性值爲LimitB時,用於驗證輸入字符的字節數是否在[min, max]區間。

 

語法 msg="string"
類型:字符串。必選。
說明:在驗證失敗時要提示的出錯信息。

 

語法operator="NotEqual | GreaterThan | GreaterThanEqual | LessThan | LessThanEqual | Equal"
類型:字符串。在dataType屬性值爲Compare時可選(默認值爲Equal)。
說明:參考to屬性。
各選值所對應的關係操作符
可選值 意義說明
NotEqual
不等於 !=
GreaterThan
大於 >
GreaterThanEqual
大於等於 >=
LessThan
小於 <
LessThanEqual
小於等於 <=
Equal 等於 =

 

語法require="true | false"
類型:字符串。可選。
說明:用於設定表單項的驗證方式。當值爲false時表單項不是必填項,但當有填寫時,仍然要執行dataType屬性所設定的驗證方法,值爲true或任何非false字符時可省略此屬性。

 

語法to="sting | int"
類型:字符串。當dataType值爲RepeatCompare時必選。
說明:當dataType值爲Repeat時,to的值爲某表單項的name屬性值,用於設定當前表單項的值是否與目標表單項的值一致;當dataType的值爲Compare時,to的選值類型爲實數,用於判斷當前表單項的輸入與to的值是否符合operator屬性值所指定的關係。

 

語法format="ymd | dmy"
類型:字符串。在dataType屬性值爲Date時可選(默認值爲ymd)。
說明:用於驗證輸入是否爲符合format屬性值所指定格式的日期。
符合規則的輸入示例 : 2004-11-232004/11/2304.11.2323-11-2004
注意:當輸入的年份爲2位時,如果數值小於30,將使年份看作處於21世紀,否則爲20世紀。

 

語法regexp="object"
類型:字符串。在dataType屬性值爲Custom時必選。
說明:用於驗證輸入是否符合regexp屬性所指定的正則表達式。

示例:

 

 

引用:http://www.phpchina.com/?1133/action_viewspace_itemid_3631.html

http://www.phpchina.com/?8133/action_viewspace_itemid_3214.html

 

示例是html代碼,不會上傳,copy過來變成頁面了,用帖子回覆又可以了。

 

元字符:

/b 代表着單詞的開頭或結尾,也就是單詞的分界處.如果要精確地查找hi這個單詞的話,我們應該使用/bhi/b.

.是另一個元字符,匹配除了換行符以外的任意字符,*同樣是元字符,它指定*前邊的內容可以重複任意次以使整個表達式得到匹配。


.*連在一起就意味着任意數量的不包含換行的字符。

/d是一個新的元字符,匹配任意的數字,0/d/d-/d/d/d/d/d/d/d/d也就是中國的電話號碼.爲了避免那麼多煩人的重複,我們也可以這樣寫這個表達式:0/d{2}-/d{8}。

/s匹配任意的空白符,包括空格,製表符(Tab),換行符,中文全角空格等。/w匹配字母或數字或下劃線或漢字。

/b/w{6}/b 匹配剛好6個字母/數字的單詞。

字符轉義:使用/來取消這些字符的特殊意義。因此,你應該使用/.和/*。當然,要查找/本身,你也得用//。

  代碼     說明
   .  匹配除換行符以外的任意字符
  /w  匹配字母或數字或下劃線或漢字
  /s  匹配任意的空白符
  /d  匹配數字
  /b  匹配單詞的開始或結束
  ^   匹配字符串的開始
  $   匹配字符串的結束

重複:
常用的限定符
代碼/語法  說明
   *  重複零次或更多次
   +  重複一次或更多次
   ?  重複零次或一次
  {n} 重複n次
{n,} 重複n次或更多次
{n,m} 重複n到m次

要想查找數字,字母或數字,你只需要在中括號裏列出它們就行了,像[aeiou]就匹配任何一個元音字母,[.?!]匹配標點符號(.或?或!)

反義:
常用的反義代碼
代碼/語法   說明
   /W   匹配任意不是字母,數字,下劃線,漢字的字符
   /S   匹配任意不是空白符的字符
   /D   匹配任意非數字的字符
   /B   匹配不是單詞開頭或結束的位置
[^x]   匹配除了x以外的任意字符
      [^aeiou]   匹配除了aeiou這幾個字母以外的任意字符


替換:
   正則表達式裏的替換指的是有幾種規則,如果滿足其中任意一種規則都應該當成匹配,具體方法是用|把不同的規則分隔開。
   0/d{2}-/d{8}|0/d{3}-/d{7}這個表達式能匹配兩種以連字號分隔的電話號碼:一種是三位區號,8位本地號(如010-12345678),一種是4位區號,7位本地號(0376-2233445)。
   /(0/d{2}/)[- ]?/d{8}|0/d{2}[- ]?/d{8}這個表達式匹配3位區號的電話號碼,其中區號可以用小括號括起來,也可以不用,區號與本地號間可以用連字號或空格間隔,也可以沒有間隔。你可以試試用替換|把這個表達式擴展成也支持4位區號的。
   /d{5}-/d{4}|/d{5}這個表達式用於匹配美國的郵政編碼。美國郵編的規則是5位數字,或者用連字號間隔的9位數字。之所以要給出這個例子是因爲它能說明一個問題:使用替換時,順序是很重要的。如果你把它改成/d{5}|/d{5}-/d{4}的話,那麼就只會匹配5位的郵編(以及9位郵編的前5位)。原因是匹配替換時,將會從左到右地測試每個分枝條件,如果滿足了某個分枝的話,就不會去管其它的替換條件了。

分組:

如果想要重複一個字符串又該怎麼辦?你可以用小括號來指定子表達式(也叫做分組),然後你就可以指定這個子表達式的重複次數了。
     (/d{1,3}/.){3}/d{1,3}是一個簡單的IP地址匹配表達式。要理解這個表達式,請按下列順序分析它:/d{1,3}匹配1到3位的數字,(/d{1,3}/.}{3}匹配三位數字加上一個英文句號(這個整體也就是這個分組)重複3次,最後再加上一個一到三位的數字(/d{1,3})。不幸的是,它也將匹配256.300.888.999這種不可能存在的IP地址(IP地址中每個數字都不能大於255)。如果能使用算術比較的話,或許能簡單地解決這個問題,但是正則表達式中並不提供關於數學的任何功能,所以只能使用冗長的分組,選擇,字符類來描述一個正確的IP地址:((2[0-4] /d|25[0-5]|[01]?/d/d?)/.){3}(2[0-4]/d|25[0-5]|[01]?/d/d?)。

後向引用:

後向引用用於重複搜索前面某個分組匹配的文本。例如,/1代表分組1匹配的文本。難以理解?請看示例:
/b(/w+)/b/s+/1/b可以用來匹配重複的單詞,像go go, kitty kitty。首先是一個單詞,也就是單詞開始處和結束處之間的多於一個的字母或數字(/b(/w+)/b),然後是1個或幾個空白符(/s+,最後是前面匹配的那個單詞(/1)。

懶惰限定符
*? 重複任意次,但儘可能少重複
+? 重複1次或更多次,但儘可能少重複
?? 重複0次或1次,但儘可能少重複
{n,m}? 重複n到m次,但儘可能少重複
{n,}? 重複n次以上,但儘可能少重複

位置指定:


接下來的四個用於查找在某些內容(但並不包括這些內容)之前或之後的東西,也就是說它們用於指定一個位置,就像/b,^,$那樣,因此它們也被稱爲零寬斷言。最好還是拿例子來說明吧:

(?=exp)也叫零寬先行斷言,它匹配文本中的某些位置,這些位置的後面能匹配給定的後綴exp。比如/b/w+(?=ing/b),匹配以 ing結尾的單詞的前面部分(除了ing以外的部分),如果在查找I'm singing while you're dancing.時,它會匹配sing和danc。

(?<=exp)也叫零寬後行斷言,它匹配文本中的某些位置,這些位置的前面能給定的前綴匹配exp。比如(?<=/bre)/w+/b會匹配以re開頭的單詞的後半部分(除了re以外的部分),例如在查找reading a book時,它匹配ading。

假如你想要給一個很長的數字中每三位間加一個逗號(當然是從右邊加起了),你可以這樣查找需要在前面和裏面添加逗號的部分:((?<=/d)/d{3})*/b。請仔細分析這個表達式,它可能不像你第一眼看出來的那麼簡單。

下面這個例子同時使用了前綴和後綴:(?<=/s)/d+(?=/s)匹配以空白符間隔的數字(再次強調,不包括這些空白符)。

負向位置指定:


前面我們提到過怎麼查找不是某個字符或不在某個字符類裏的字符的方法(反義)。但是如果我們只是想要確保某個字符沒有出現,但並不想去匹配它時怎麼辦?例如,如果我們想查找這樣的單詞--它裏面出現了字母q,但是q後面跟的不是字母u,我們可以嘗試這樣:

/b/w*q[^u]/w*/b匹配包含後面不是字母u的字母q的單詞。但是如果多做測試(或者你思維足夠敏銳,直接就觀察出來了),你會發現,如果q出現在單詞的結尾的話,像Iraq,Benq,這個表達式就會出錯。這是因爲[^u]總是匹配一個字符,所以如果q是單詞的最後一個字符的話,後面的 [^u]將會匹配q後面的單詞分隔符(可能是空格,或者是句號或其它的什麼),後面的/w+/b將會匹配下一個單詞,於是/b/w*q[^u]/w*/b 就能匹配整個Iraq fighting。負向位置指定能解決這樣的問題,因爲它只匹配一個位置,並不消費任何字符。現在,我們可以這樣來解決這個問題:/b/w*q(?!u) /w*/b。

零寬負向先行斷言(?!exp),只會匹配後綴exp不存在的位置。/d{3}(?!/d)匹配三位數字,而且這三位數字的後面不能是數字。

同理,我們可以用(?<!exp),零寬負向後行斷言來查找前綴exp不存在的位置:(?<![a-z])/d{7}匹配前面不是小寫字母的七位數字(實驗時發現錯誤?注意你的“區分大小寫”先項是否選中)。

一個更復雜的例子:(?<=<(/w+)>).*(?=<///1>)匹配不包含屬性的簡單HTML標籤內裏的內容。(<?(/w+)>)指定了這樣的前綴:被尖括號括起來的單詞(比如可能是<b>),然後是.*(任意的字符串),最後是一個後綴(?=<///1>)。注意後綴裏的//,它用到了前面提過的字符轉義;/1則是一個反向引用,引用的正是捕獲的第一組,前面的(/w +)匹配的內容,這樣如果前綴實際上是<b>的話,後綴就是</b>了。整個表達式匹配的是<b>和< /b>之間的內容(再次提醒,不包括前綴和後綴本身)。

註釋:
小括號的另一種用途是能過語法(?#comment)來包含註釋。例如:2[0-4]/d(?#200-249)|25[0-5](?#250-255)|[01]?/d/d?(?#0-199)。

要包含註釋的話,最好是啓用“忽略模式裏的空白符”選項,這樣在編寫表達式時能任意的添加空格,Tab,換行,而實際使用時這些都將被忽略。啓用這個選項後,在#後面到這一行結束的所有文本都將被當成註釋忽略掉。

例如,我們可以前面的一個表達式寫成這樣:

      (?<=    # 查找前綴,但不包含它
      <(/w+)> # 查找尖括號括起來的字母或數字(標籤)
      )       # 前綴結束
      .*      # 匹配任意文本
      (?=     # 查找後綴,但不包含它
      <///1>  # 查找尖括號括起來的內容:前面是一個"/",後面是先前捕獲的標籤
      )       # 後綴結束


貪婪與懶惰:
當正則表達式中包含能接受重複的限定符(指定數量的代碼,例如*, {5,12}等)時,通常的行爲是(在使整個表達式能得到匹配的前提下)匹配儘可能多的字符。考慮這個表達式:a.*b,它將會匹配最長的以a開始,以b 結束的字符串。如果用它來搜索aabab的話,它會匹配整個字符串aabab。這被稱爲貪婪匹配。

有時,我們更需要懶惰匹配,也就是匹配儘可能少的字符。前面給出的限定符都可以被轉化爲懶惰匹配模式,只要在它後面加上一個問號?。這樣.*?就意味着匹配任意數量的重複,但是在能使整個匹配成功的前提下使用最少的重複。現在看看懶惰版的例子吧:

a.*?b匹配最短的,以a開始,以b結束的字符串。如果把它應用於aabab的話,它會匹配aab和ab(爲什麼第一個匹配是aab而不是ab?簡單地說,最先開始的區配最有最大的優先權??The Match That Begins Earliest Wins)。

表5.懶惰限定符 *? 重複任意次,但儘可能少重複
+? 重複1次或更多次,但儘可能少重複
?? 重複0次或1次,但儘可能少重複
{n,m}? 重複n到m次,但儘可能少重複
{n,}? 重複n次以上,但儘可能少重複

-------------------------------------------------------

下面是一些常用的正則表達式:

匹配中文字符的正則表達式: [/u4e00-/u9fa5]
評註:匹配中文還真是個頭疼的事,有了這個表達式就好辦了

匹配雙字節字符(包括漢字在內):[^/x00-/xff]
評註:可以用來計算字符串的長度(一個雙字節字符長度計2,ASCII字符計1)

匹配空白行的正則表達式:/n/s*/r
評註:可以用來刪除空白行

匹配HTML標記的正則表達式:<(/S*?)[^>]*>.*?<//1>|<.*? />
評註:網上流傳的版本太糟糕,上面這個也僅僅能匹配部分,對於複雜的嵌套標記依舊無能爲力

匹配首尾空白字符的正則表達式:^/s*|/s*$
評註:可以用來刪除行首行尾的空白字符(包括空格、製表符、換頁符等等),非常有用的表達式

匹配Email地址的正則表達式:/w+([-+.]/w+)*@/w+([-.]/w+)*/./w+([-.]/w+)*
評註:表單驗證時很實用

匹配網址URL的正則表達式:[a-zA-z]+://[^/s]*
評註:網上流傳的版本功能很有限,上面這個基本可以滿足需求

匹配帳號是否合法(字母開頭,允許5-16字節,允許字母數字下劃線):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
評註:表單驗證時很實用

匹配國內電話號碼:/d{3}-/d{8}|/d{4}-/d{7}
評註:匹配形式如 0511-4405222 或 021-87888822

匹配騰訊QQ號:[1-9][0-9]{4,}
評註:騰訊QQ號從10000開始

匹配中國郵政編碼:[1-9]/d{5}(?!/d)
評註:中國郵政編碼爲6位數字

匹配身份證:/d{15}|/d{18}
評註:中國的身份證爲15位或18位

匹配ip地址:/d+/./d+/./d+/./d+
評註:提取ip地址時有用

匹配特定數字:
^[1-9]/d*$    //匹配正整數

 

 

例子:

<!DOCTYPE html PUBLIC "-//w3c//dtd xhtml 1.0 transitional//en" "http://www.w3.org/tr/xhtml1/dtd/xhtml1-transitional.dtd">
<html>
<head><title></title>
  
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta http-equiv="Content-Language" content="gb2312">  
<script language="javascript" type="text/javascript" src="Validator.js"></script>
</head>
<body>
<title>表單驗證類 Validator v1.05</title>
 <style>
 body,td{font:normal 12px Verdana;color:#333333}
 input,textarea,select,td{font:normal 12px Verdana;color:#333333;border:1px solid #999999;background:#ffffff}
 table{border-collapse:collapse;}
 td{padding:3px}
 input{height:20;}
 textarea{width:80%;height:50px;overflow:auto;}
 form{display:inline}
 </style>
 <table align="center">
  <form name="theform" id="demo" method="get" onSubmit="return Validator.Validate(this,2)">
  <tr>
   <td>身份證號:</td><td><input name="Card" dataType="IdCard" msg="身份證號錯誤"></td>
  </tr>
    <tr>
   <td>真實姓名:</td><td><input name="Name" dataType="Chinese" msg="真實姓名只允許中文"></td>
  </tr>
  <tr>
   <td>ID:</td><td><input name="username" dataType="Username" msg="ID名不符合規定"></td>
  </tr>
  <tr>
   <td>英文名:</td><td><input name="Nick" dataType="English" require="false" msg="英文名只允許英文字母"></td>
  </tr>
    <tr>
   <td>主頁:</td><td><input name="Homepage" require="false" dataType="Url"   msg="非法的Url"></td>
  </tr>
  <tr>
   <td>密碼:</td><td><input name="Password" dataType="SafeString"   msg="密碼不符合安全規則" type="password"></td>
  </tr>
  <tr>
   <td>重複:</td><td><input name="Repeat" dataType="Repeat" to="Password" msg="兩次輸入的密碼不一致" type="password"></td>
  </tr>
  <tr>
   <td>信箱:</td><td><input name="Email" dataType="Email" msg="信箱格式不正確"></td>
  </tr>
    <tr>
   <td>信箱:</td><td><input name="Email" dataType="Repeat" to="Email" msg="兩次輸入的信箱不一致"></td>
  </tr>
  <tr>
   <td>QQ:</td><td><input name="QQ" require="false" dataType="QQ" msg="QQ號碼不存在"></td>
  </tr>
    <tr>
   <td>身份證:</td><td><input name="Card" dataType="IdCard" msg="身份證號碼不正確"></td>
  </tr>
  <tr>
   <td>年齡:</td><td><input name="Year" dataType="Range" msg="年齡必須在18~28之間" min="18" max="28"></td>
  </tr>
   <tr>
   <td>年齡1:</td><td><input name="Year1" require="false" dataType="Compare" msg="年齡必須在18以上" to="18" operator="GreaterThanEqual"></td>
  </tr>
   <tr>
   <td>電話:</td><td><input name="Phone" require="false" dataType="Phone" msg="電話號碼不正確"></td>
  </tr>
   <tr>
   <td>手機:</td><td><input name="Mobile" require="false" dataType="Mobile" msg="手機號碼不正確"></td>
  </tr>
     <tr>
   <td>生日:</td><td><input name="Birthday" dataType="Date" format="ymd" msg="生日日期不存在"></td>
  </tr>
   <tr>
   <td>郵政編碼:</td><td><input name="Zip" dataType="Custom" regexp="^[1-9]\d{5}$" msg="郵政編碼不存在"></td>
  </tr>
  <tr>
   <td>郵政編碼:</td><td><input name="Zip1" dataType="Zip" msg="郵政編碼不存在"></td>
  </tr>
  <tr>
   <td>操作系統:</td><td><select name="Operation" dataType="Require"  msg="未選擇所用操作系統" ><option value="">選擇您所用的操作系統</option><option value="Win98">Win98</option><option value="Win2k">Win2k</option><option value="WinXP">WinXP</option></select></td>
  </tr>
  <tr>
   <td>所在省份:</td><td>廣東<input name="Province" value="1" type="radio">陝西<input name="Province" value="2" type="radio">浙江<input name="Province" value="3" type="radio">江西<input name="Province" value="4" type="radio" dataType="Group"  msg="必須選定一個省份" ></td>
  </tr>
  <tr>
   <td>愛好:</td><td>運動<input name="Favorite" value="1" type="checkbox">上網<input name="Favorite" value="2" type="checkbox">聽音樂<input name="Favorite" value="3" type="checkbox">看書<input name="Favorite" value="4" type="checkbox"" dataType="Group" min="2" max="3"  msg="必須選擇2~3種愛好"></td>
  </tr>
   <td>自我介紹:</td><td><textarea name="Description" dataType="Limit" max="10"  msg="自我介紹內容必須在10個字之內">中文是一個字</textarea></td>
  </tr>
     <td>自傳:</td><td><textarea name="History" dataType="LimitB" min="3" max="10"  msg="自傳內容必須在[3,10]個字節之內">中文是兩個字節t</textarea></td>
  </tr>
    <tr>
   <td>相片上傳:</td><td><input name="up" dataType="Filter" msg="非法的文件格式" type="file" accept="jpg, gif, png"></td>
  </tr>
  <tr>
   <td colspan="2"><input name="Submit" type="submit" value="確定提交"><input onClick="Validator.Validate(document.getElementById('demo'))" value="檢驗模式1" type="button"><input onClick="Validator.Validate(document.getElementById('demo'),2)" value="檢驗模式2" type="button"><input onClick="Validator.Validate(document.getElementById('demo'),3)" value="檢驗模式3" type="button"></td>
  </tr>
  </form>
 </table>
</body>

</html>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章