正则表达式!!谁想了解的请看,有问题大家探讨

beming 2002-09-17 01:56:06
「正規表示法」或「正規式」(Regular expressions)是在 UNIX 世界中發展出來的字串比對技巧,其基本概念是用一套簡單(但功能強大)的符號來比對字串,並可對符合比對條件的字串進行修改或其他運算。事實上,UNIX 的許多軟體或指令都支援正規表示法,例如 grep、sed、awk、ed、vi、emacs 等。(這些東西大概只有像我這樣的 LKK 才會用。)尤其是 Perl,更是將正規表示法發揮的淋漓盡致。

Netscape 及 IE 在第四版後都支援 JavaScript 的正規表示法,特別適用於表單資料的驗證與修改。事實上,JavaScript 的正規表示法和 Perl 幾乎一模一樣,因此,在本章學到的正規表示法,也可以完全適用於 Perl。(一魚兩吃,簡直太棒了!)

JavaScript 的正規式(Regular expressions)是一個內建的物件,其建構函示(Construction functoin)為 RegExp,典型用法如下:

re = new RegExp("pattern", "flag")

上述用法也可以寫成:
re = /pattern/flag

其中,pattern 代表以正規表示法來顯示的字串,flag 則是比對的方式。flag 的值可能有三種,分別解釋如下:
g:全域比對(Global match)
i:忽略大小寫(Ignore case)
gi:全域比對並忽略大小寫
舉例來說,我們的身份證字號的格式是由一個英文字母加上九個數字組合而成,如果我們要求使用者輸入身份證字號,就可以使用 JavaScript 的正規表示法來驗證其格式的正確性。例如,我們可用下列表單來要求使用者輸入身份證字號:

身份證字號:(第一個英文字母需大寫)
在上例中,我們利用 onBlur 事件來進行正規式的比對,換句話說,當使用者填完資料,要離開此欄位的時候,JavaScript 即會測知 onBlur 事件,並呼叫函數 checkID() 來對填入的資料進行驗證。(欲測試其效果,只需刪除欄位內的任一個字元,再到欄位外點一下,就可以看到警告視窗了。)相關原始碼如下:

<SCRIPT>
function checkID(formElement) {
re = /^[A-Z]\d{9}$/;
if (!re.test(formElement.value))
alert("你的身份證號碼格式不對!");
}
</SCRIPT>

<FORM>身份證字號:<INPUT onblur=checkID(this) value=A000000000>(第一個英文字母需大寫) </FORM>
在上述原始碼中,/^[A-Z]\d{9}$/ 就是一個正規式,[A-Z] 代表由 A 至 Z 的所有可能英文字母,\d 代表由 0 至 9 的數目字(事實上也可以寫成 [0-9]),{9} 則代表需要有九個數目字,^ 代表字串開始位置,$ 代表字串結束位置,因此 /^[A-Z]\d{9}$/ 就代表可以比對身份證字號的正規式。formElement.value 代表使用者輸入的字串,re.test() 則會傳回 true 或 false,代表比對是否成功。若要不限定是大寫英文字母,只需將正規式改成 /^[a-zA-Z]\d{9}$/g 就可以了!(注意:若不加入 ^ 和 $,那麼 /[A-Z]\d{9}/ 就會比對到其他不合法的身份證字號,例如 AGF123456789 或是 F1234567890 等。因此,加入 ^ 和 $ 可保證比對正確的字串一定是由由一個大寫英文字母加上九個數字所構成。)

事實上,身份證字號本身就有內在的編碼規則,這些規則和使用者的性別有關,因此若要實現較完整的表單驗證,就必須應用較完整的身份證編碼規則。

另一個簡單的例子,是要求使用者輸入信用卡號碼,這是一組16個數字的號碼,例如:

信用卡號碼:(格式:xxxx-xxxx-xxxx-xxxx)
當 onBlur 發生時,換句話說,JavaScript 會呼叫函數 checkCreditCard( ) 來對填入的資料進行驗證。相關原始碼如下:

<SCRIPT>
function checkCreditCard(control) {
re = /^\d{4}-\d{4}-\d{4}-\d{4}$/;
if (!re.test(control.value))
alert("你的信用卡號碼不符合「xxxx-xxxx-xxxx-xxxx」的格式!");
}
</SCRIPT>

<FORM>信用卡號碼:<INPUT onblur=checkCreditCard(this) value=xxxx-xxxx-xxxx-xxxx>(格式:xxxx-xxxx-xxxx-xxxx) </FORM>
在上例中,很顯然地,/^\d{4}-\d{4}-\d{4}-\d{4}$/ 就代表正確的信用卡格式。

下一個例子,則是用正規表示法來驗證使用者的英文名字,例如:

你的英文全名:(格式:First Last 或 First Middle Last)
當 onBlur 發生時,換句話說,JavaScript 會呼叫函數 checkEnglishName( ) 來對填入的資料進行驗證。相關原始碼如下:

<SCRIPT>
function checkEnglishName(control) {
re1 = /^[A-Za-z\-]+\s+[A-Za-z\-]+$/;
re2 = /^[A-Za-z\-]+\s+[A-Za-z\-]+\s+[A-Za-z\-]+$/;
if (!re1.test(control.value) && !re2.test(control.value))
alert("你的英文名字格式不對!");
}
</SCRIPT>

<FORM>你的英文全名:<INPUT onblur=checkEnglishName(this)>(格式:First Last 或 First Middle Last) </FORM>

正規式物件的方法可列表如下:

正規式物件的方法 功能
re.compile(pattern, flag) 對正規式物件 re 進行編譯,以增加比對速度
re.exec(string) 或 re(string) 比對正規式,並傳回陣列
re.test(string) 比對正規式,並傳回比對結果(成功或失敗)


在上述範例中,我們只用到了正規式物件的 test() 方法來判斷比對是否成功,其他方法會在後序章節提到。

在進行表單資料驗證之前,我們應先進行表單資料修改,例如拿掉不必要的空格、英文字母大小寫轉換等,這些工作也可以由字串的 replace() 方法或正規式的 exec() 方法來達成,這是我們下一節的主題。

在下列的表格中,我們使用幾個簡單的範例來對正規式的應用做較完整的說明:

正規式 說明及範例 比對不成立之字串
/a/ 含字母 "a" 的字串,例如:"ab", "bac", "cba" "xyz"
/a./ 含字母 "a" 以及其後任一個字元的字串,例如:"ab", "bac" "a", "ba"
/^xy/ 以 "xy" 開始的字串,例如:"xyz", "xyab" "axy", "bxy"
/xy$/ 以 "xy" 結尾的字串,例如:"axy", "abxy" "xya", "xyb"
[13579] 包含 "1" 或 "3" 或 "5" 或 "7" 或 "9" 的字串,例如:"a3b", "1xy" "y2k"
[0-9] 含數字之字串 不含數字之字串
[a-z0-9] 含數字或小寫字母之字串 不含數字及小寫字母之字串
[a-zA-Z0-9] 含數字或字母之字串 不含數字及字母之字串
b[aeiou]t "bat", "bet", "bit", "bot", "but" "bxt", "bzt"
[^0-9] 不含數字之字串 含數字之字串
[^aeiouAEIOU] 不含母音之字串 含母音之字串
[^\^] 不含 "^" 之字串,例如:"xyz", "abc" "xy^", "a^bc"


請注意在上表中,"^" 在兩條斜線中,代表一個字串的開始位置,因此 /^xy/ 代表以 "xy" 開始的字串。同理,"$" 在兩條斜線中,代表一個字串的結束位置,因此 /xy$/ 代表以 "xy" 結束的字串。但是如果將 "^" 放在兩個方括弧中,就代表「否定」,因此 [^aeiouAEIOU] 代表不含母音之字串。

有些正規式會常被用到,因此已被定義為特定字元,這些字元可列表說明如下:

正規表示法的特定字元 說明 等效的正規表示法
\d 數字 [0-9]
\D 非數字 [^0-9]
\w 數字、字母、底線 [a-zA-Z0-9_]
\W 非 \w [^a-zA-Z0-9_]
\s 空白字元 [\r\t\n\f]
\S 非空白字元 [^\r\t\n\f]


此外,我們可定義字元的重複次數,如下:

正規表示法 說明
/a?/ 零或一個 a
/a+/ 一或多個 a
/a*/ 零或多個 a
/a{4}/ 四個 a
/a{5,10}/ 五至十個 a
/a{5,}/ 至少五個 a
/a{,3} 至多三個 a
/a.{5}b/ a 和 b中間夾五個(非換行)字元


各位現在已經可以慢慢體會到正規表示式的威力了!利用同樣的方法,我們可以對各式各樣的表單輸入進行驗證,請參考下述範例。

注意事項
以 RegExp(pattern, flag) 的方式來建立正規式物件時,若 pattern 包含以反斜線開頭的特殊字元(例如 \d、\w、\s 等)時,我們必須再加上一個反斜線來保留其特殊意義。例如:
re = /\d+\s\w+/g

以 RegExp 為主的等效表示法為:
re = new RegExp("\\d+\\s\\w+", "g");

...全文
110 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
beming 2002-09-19
  • 打赏
  • 举报
回复
关注者有分~~~~~~~
yesgo 2002-09-19
  • 打赏
  • 举报
回复
送大家几个使用正则表达式校验字符串的例子,这是一个完整的页面:

<html>
<head>
<title>凤君出品,必属精品!</title>
<style>TD {FONT-SIZE: 12px; COLOR: #333333;}</style>

<SCRIPT language="JavaScript">
<!--
/*
*Author:赵凤君
*Function:关于字符串的表单校验函数
*Create:September 14, 2002
*/
/*这函数的作用是当页面装在完毕后默认把焦点放在第一个表单域,需要结合body的onload()事件*/
function focusInFirst(){
document.forms[0].elements[0].focus();
}
/*判断用户输入是否为空,也即无输入的情况。*/
function isEmpty(ui) {
return (ui==null||ui=="");}
/*判断是否用户输入全为数字*/
function isNumber(ui) {
var notValid=/\D{1,}/;
return (!notValid.test(ui));}
/*判断用户输入是否全为字母*/
function isLetter(ui) {
var valid=/^[a-zA-Z]*$/;
return (valid.test(ui));}
/*判断用户输入的字符串必须为数字、字母或者下划线(_)*/
function isNLU(ui) {
var valid=/^\w*$/;
return (valid.test(ui));}
/*这个方法跟上面的isNLU()实现相同的功能,效率也很高,但由于循环的原因,比上面的方法还是差很多。*/
/*本例子后面的校验中并没有调用该方法,只是方便您参考而已。*/
function isNumLetUnd(ui){
var valid="0123456789abcdefghijklmnopqrstuvwxwzABCDEFGHIJKLMNOPQRSTUVWXYZ_";
for(var i=0;i<ui.length;i++){
if(valid.indexOf(ui.charAt(i))==-1)
return false;}
return true;}
/*判断用户输入的字符串必须为数字、字母或者下划线(_),且最少同时包含数字和字母,下划线可输入也可不输入*/
function isIncNL(ui) {
var valid=/^\w{2,}$/;
var validNum=/\d+/;
var validLet=/[a-zA-Z]+/;
return (isEmpty(ui)||(valid.test(ui)&&validNum.test(ui)&&validLet.test(ui)));}
/*判断用户输入的字符串必须为数字、字母或者下划线(_),且最少同时包含数字、字母、下划线*/
function isIncNLU(ui) {
var valid=/^\w{3,}$/;
var validNum=/\d+/;
var validLet=/[a-zA-Z]+/;
var validSym=/\_+/;
return (isEmpty(ui)||(valid.test(ui)&&validNum.test(ui)&&validLet.test(ui)&&validSym.test(ui)));}
/*有很多符号是不可以允许用户输入的,否则你在JSP中request.getParameter()后会导致程序错误,尤其是单引号!
*本函数禁用了可能引起错误的所有字符!*/
function isIncSym(ui) {
var valid=/[\'\"\,\<\>\+\-\*\/\%\^\=\\\!\&\|\(\)\[\]\{\}\:\;\~\`\#\$]+/;
return (valid.test(ui));}
/*有的时候我们要求用户必须输入或者禁止输入指定的字符或者字符串,用下面的函数就够了*/
function isInc(ui,udSub) {
return (ui.indexOf(udSub)!=-1);}
/*判断用户输入字符串的长度是否在指定范围内。*/
/*需要注意的是,这只是一个简单的判断,处理双字节会有问题,如果你不知如何判断含有双字节串的长度,请你告诉我。*/
function lenCheck(ui,minl,maxl) {
return (ui.length>=minl&&ui.length<=maxl);}

function formCheck(){
if(!isNumber(document.forms[0].only_num.value)){
alert("该域只允许输入数字!");
document.forms[0].only_num.focus();
return false;}
if(!isLetter(document.forms[0].only_let.value)){
alert("该域只允许输入字母!");
document.forms[0].only_let.focus();
return false;}
if(!isNLU(document.forms[0].in_nlu.value)){
alert("该域只允许输入字母、数字或者下划线!");
document.forms[0].in_nlu.focus();
return false;}
if(!isIncNL(document.forms[0].inc_nl.value)){
alert("该域只允许输入字母、数字或下划线,至少包含字母和数字!");
document.forms[0].inc_nl.focus();
return false;}
if(!isIncNLU(document.forms[0].inc_nlu.value)){
alert("该域只允许且同时包含输入字母、数字和下划线!");
document.forms[0].inc_nlu.focus();
return false;}
if(isIncSym(document.forms[0].no_inc_sym.value)){
alert("该域包含了系统禁用的字符!");
document.forms[0].no_inc_sym.focus();
return false;}
if(isInc(document.forms[0].no_inc_this.value,"roc")){
alert("该域包含了用户指定禁用的字符!");
document.forms[0].no_inc_this.focus();
return false;}
if(!isEmpty(document.forms[0].inc_this.value)&&!isInc(document.forms[0].inc_this.value,"zhao")){
alert("该域没有包含用户指定的必须包含的字符!");
document.forms[0].inc_this.focus();
return false;}
if(!isNLU(document.forms[0].len.value)){
alert("该域只允许输入字母、数字或者下划线!");
document.forms[0].len.focus();
return false;}
if(!lenCheck(document.forms[0].len.value,3,6)){
alert("该域要求输入3到6个字符!");
document.forms[0].len.focus();
return false;}
alert("恭喜恭喜!表单校验全部通过!");
/*下面一段是我写着玩的,如果你觉得烦,可以注释掉*/
/*废话从这里开始...*/
var feedback="课后作业:\n\n\r本例程要实现的功能有BUG吗?\n\r您还有其他表单校验问题吗?\n\r实现本例中的功能,您有或者见过更为简洁高效的方法吗?\n\r如有上述问题,万望写信告诉我!\n\n\r简洁高效,精益求精,是我一贯的追求!\n\n\r赵凤君 roczhao@msn.com";
if(confirm(feedback)){
alert("真的吗?那你可要写信告诉我哦!");
location="mailto:roczhao@msn.com?subject=反馈意见(关于你的表单校验脚本)";}
else
alert("\n\r哼,我就知道你会点取消!\n\r你干嘛不点一下确定呢?或许会有奇遇发生哦!\n\n\r感谢使用!");
/*...废话到这里结束!*/
}
//-->
</SCRIPT>

</head>

<body bgcolor="#FFFFFF" onLoad="focusInFirst()">
<center>
<font color="#FF6600">表单校验测试页面</font>
<hr width="60%" color="#000000" size="1" noshade>
<font style="FONT-SIZE: 12px; COLOR:red;">注意:本例除最后一个输入框外,前面的表单域是没有校验长度的,但当你输入数据的时候将激发校验。</font>
<form name="testForm">
<table width="600" border="1" cellspacing="2" cellpadding="0">
<tr>
<td colspan="2"> </td>
</tr>
<tr>
<td width="261">只能输入数字:</td>
<td width="213">
<input type="text" name="only_num">
</td>
</tr>
<tr>
<td width="261">只能输入字母:</td>
<td width="213">
<input type="text" name="only_let">
</td>
</tr>
<tr>
<td width="261">只能输入字母、数字或下划线:</td>
<td width="213">
<input type="text" name="in_nlu">
</td>
</tr>
<tr>
<td width="261">只能输入字母、数字或下划线,且必须同时包含字母和数字:</td>
<td width="213">
<input type="text" name="inc_nl">
</td>
</tr>
<tr>
<td width="261">只能输入字母、数字或下划线,且必须同时包含字母、数字和下划线:</td>
<td width="213">
<input type="text" name="inc_nlu">
</td>
</tr>
<tr>
<td colspan="2">  </td>
</tr>
<tr>
<td width="261">禁止包含预指定的字符('",<>+-*/%^=\!&|()[]{}:;~`#$):</td>
<td width="213">
<input type="text" name="no_inc_sym">
</td>
</tr>
<tr>
<td width="261">禁止包含用户指定的字符串(本例中为<font color="#FF0000">roc</font>):</td>
<td width="213">
<input type="text" name="no_inc_this">
</td>
</tr>
<tr>
<td width="261">必须包含用户指定的字符串(本例中为<font color="#FF0000">zhao</font>):</td>
<td width="213">
<input type="text" name="inc_this">
</td>
</tr>
<tr>
<td width="261">只能输入数字、字母或者下划线,且要求长度在3到6之间:</td>
<td width="213">
<input type="text" name="len">
</td>
</tr>
<tr>
<td width="261"> </td>
<td width="213"> </td>
</tr>
<tr>
<td width="261"> </td>
<td width="213">
<input type="button" name="test" value="测试" onClick="return formCheck();">
</td>
</tr>
</table>
</form>
</center>
</body>
</html>
yesgo 2002-09-19
  • 打赏
  • 举报
回复
我倒!很简单呀,有什么可探讨的?

81,091

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧