目錄
正則表達式( ,常常縮寫為 )是一種用特殊符號編寫的模式,描述一個
或多個文本字符串。使用正則表達式匹配文本的模式,這樣腳本就可以輕松地識別和操縱文本。與算
術表達式一樣,創建正則表達式也要使用操作符,但是在這種情況下使用的是操作文本(而不是數字)
的操作符。
7.1 用正則表達式驗證電子郵件地址
電子郵件驗證示例的 HTML
<!DOCTYPE html>
<html>
<head>
<title>Email Validation</title>
<link rel="stylesheet" href="script01.css">
<script src="script01.js"></script>
</head>
<body>
<h2 class="centered">Email Validation</h2>
<form action="someAction.cgi">
<p><label for="emailAddr">Email Address:<input id="emailAddr" type="text" size="30" class="email">
</label></p>
<p><input type="submit" value="Submit"> <input type="reset"></p>
</form>
</body>
</html>
body {
color: #000;
background-color: #FFF;
}
input.invalid {
background-color: #FF9;
border: 2px red inset;
}
label.invalid {
color: #F00;
font-weight: bold;
}
.centered {
text-align: center;
}
window.onload = function() {
document.forms[0].onsubmit = validForm;
}
function validForm() {
var allGood = true;
var allTags = document.forms[0].getElementsByTagName("*");
for (var i=0; i<allTags.length; i++) {
if (!validTag(allTags[i])) {
allGood = false;
}
}
return allGood;
function validTag(thisTag) {
var outClass = "";
var allClasses = thisTag.className.split(" ");
for (var j=0; j<allClasses.length; j++) {
outClass += validBasedOnClass(allClasses[j]) + " ";
}
thisTag.className = outClass;
if (outClass.indexOf("invalid") > -1) {
invalidLabel(thisTag.parentNode);
thisTag.focus();
if (thisTag.nodeName == "INPUT") {
thisTag.select();
}
return false;
}
return true;
function validBasedOnClass(thisClass) {
var classBack = "";
switch(thisClass) {
case "":
case "invalid":
break;
case "email":
if (allGood && !validEmail(thisTag.value)) {
classBack = "invalid";
}
default:
classBack += thisClass;
}
return classBack;
}

function validEmail(email) {
var re = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/;
return re.test(email);
}
function invalidLabel(parentTag) {
if (parentTag.nodeName == "LABEL") {
parentTag.className += "invalid";
}
}
}
}
1. var re = /^\w+([.-]?\w+)@\w+([.-]?\w+)(.\w{2,3})+$/;
正則表達式總是以斜杠( /)開頭和結尾(當然,仍然有一個分號,表示 代碼行結束,
但分號不是正則表達式的一部分)。斜杠之間的所有內容都是正則表達式的組成部分。
脫字符( ^)表示我們要使用這個表達式檢查以特定的字符串開頭的字符串。如果去掉脫字符,
那么即使字符串開頭有一堆“垃圾字符”,電子郵件地址也可能被認為是有效的。
表達式\w 表示任意單一字符,包括 a~ z、 A~ Z、 0~ 9 和下劃線。電子郵件地址必須以這些字符
之一開頭。
加號+表示我們要尋找前面條目的一次或多次出現。在這個示例中,電子郵件地址必須以字符 a~ z、
A~ Z、 0~ 9 或下劃線的任意組合開頭。
左圓括號(表示一個組。這意味著后面將要引用圓括號中的所有內容,所以現在將它們放在一個
組中。
方括號[]用來表示可以出現在其中的任意一個字符。在這個示例中,方括號內包含字符.-。我
們希望允許用戶輸入點號或連字符,但是點號對于正則表達式有特殊意義,所以需要在它前面加上反
斜杠\,這表示我們指的實際上是點號本身,而不是它的特殊意義。在特殊字符前面使用反斜杠稱為
“對字符轉義”。因為有方括號,輸入的字符串在這個位置可以有一個點號或一個連字符,但是兩者不
能同時存在。注意,連字符不代表任何特殊字符,所以不用加反斜杠。
問號?表示前面的條目可以不出現或者出現一次。所以,在電子郵件地址的第一部分(在@前面的
部分)中可以有一個點號或一個連字符,也可以沒有。
在?后面,再次使用\w+,這表示點號或連字符后面必須有其他一些字符。
右圓括號)表示這個組結束了。在此之后是一個星號,表示前面的條目(在這個示例中,指圓括
號中的所有內容)可以不出現或者出現多次。所以如果 dori 是有效的電子郵件前綴, --1-2-3
也是。
@字符僅僅代表它本身,沒有任何其他意義,這個字符位于電子郵件地址前綴和域名之間。
再次使用\w+,這表示域名必須以一個或多個 a~ z、 A~ Z、 0~ 9 或下劃線字符開頭。在此之后同
樣是([.-]?\w+)*,表示電子郵件地址的后綴中允許有點號或連字符。
然后,在一對圓括號中建立另一個組: .\w{2,3},表示我們希望找到一個點號,后面跟著一些字
符。在這個示例中,花括號中的數字表示前面的條目(本例中是\w,表示字母、數字或下劃線)可以
出現 2 次或 3 次。在這個組的右圓括號后面是一個+,也表示前面的條目(這個組)必須出現一次或
多次。這會匹配.com 或.edu 之類的,也與 ox.ac.uk 匹配。
最后,正則表達式的末尾是一個美元符號$,表示匹配的字符串必須在這里結束。這使腳本能夠
拒絕那些開頭正確,但是在末尾包含垃圾字符的電子郵件地址。斜杠結束正則表達式。分號和原來一
樣結束 語句。
7.2 驗證文件名
可以用正則表達式做許多事情,但是最有用的功能之一是驗證網頁上表單中的輸入字段。希望用戶輸入一個圖像的有效 URL,正則表達式有助于確保用戶的輸入符合要求(具體地說,文件名必須有表示圖像文件的后綴)。
window.onload = function() {
document.forms[0].onsubmit = validForm;
}
function validForm() {
var allGood = true;
var allTags = document.forms[0].getElementsByTagName("*");
for (var i=0; i<allTags.length; i++) {
if (!validTag(allTags[i])) {
allGood = false;
}
}
return false;
function validTag(thisTag) {
var outClass = "";
var allClasses = thisTag.className.split(" ");
for (var j=0; j<allClasses.length; j++) {
outClass += validBasedOnClass(allClasses[j]) + " ";
}
thisTag.className = outClass;
if (outClass.indexOf("invalid") > -1) {
invalidLabel(thisTag.parentNode);
thisTag.focus();
if (thisTag.nodeName == "INPUT") {
thisTag.select();
}
return false;
}
return true;
function validBasedOnClass(thisClass) {
var classBack = "";
switch(thisClass) {
case "":
case "invalid":

break;
case "imgURL":
if (allGood && !setImgURL(thisTag.value)) {
classBack = "invalid ";
}
default:
classBack += thisClass;
}
return classBack;
}
function setImgURL(newURL) {
var re = /^(file|http):\/\/\S+\/\S+\.(gif|jpg|png)$/i;
if (re.test(newURL)) {
document.getElementById("chgImg").src = newURL;
return true;
}
return false;
}
function invalidLabel(parentTag) {
if (parentTag.nodeName == "LABEL") {
parentTag.className += "invalid";
}
}
}
}
var re = /^(file|http):\/\/\S+\/\S+\.(gif|jpg/png)$/i;
這行代碼在 imgURL()函數中。與前一個示例一樣,我們希望檢查輸入的整個字段,所以正則表達
式以/^開頭,以$/結束。輸入可以以文本 http 或 file 開頭,所以將這兩個字符串放在一個組中,用|
分隔,表示可以接受兩者之一。無論用戶是從本地硬盤還是從 Web 獲得圖像, ://幾個字符都是必需
的,所以接下來檢查這些字符。注意,每個正斜杠必須分別進行轉義(這里的兩處\/都是轉義后的正
斜杠),因為正斜杠是正則表達式特殊字符。
在此之后,幾乎可以出現任何字符,所以使用\S+表示后面是一個或多個非空格字符。然后需要
另一個正斜杠(同樣經過轉義)來分隔域名和文件名,然后是另一個\S+用來處理文件名。
文件名需要以點號和 gif、 jpg 和 png 結束。點號經過轉義,兩個后綴組合在一起,表示接受其中之一。
在這個正則表達式后面,使用修飾符 i 允許用戶輸入大寫或小寫字母。這個修飾符讓正則表達式
不區分大小寫
7.3 提取字符串
我們獲得一系列輸入的姓名,其中名字在前,姓氏在后qq輸入法完成字符串,然后交換名和姓的次序.
window.onload = function() {
document.forms[0].onsubmit = validForm;
}
function validForm() {
var allTags = document.forms[0].getElementsByTagName("*");
for (var i=0; i<allTags.length; i++) {
validTag(allTags[i]);
}
return false;
function validTag(thisTag) {
var allClasses = thisTag.className.split(" ");
for (var j=0; j<allClasses.length; j++) {
if (allClasses[j] == "nameList") {
thisTag.value = setNameList(thisTag.value);
}
}
function setNameList(inNameList) {
var newNames = new Array;
var newNameField = "";
var re = /\s*\n\s*/;
var nameList = inNameList.split(re);
re = /(\S+)\s(\S+)/;
for (var k=0; k<nameList.length; k++) {
newNames[k] = nameList[k].replace(re, "$2, $1");
}
for (k=0; k<newNames.length; k++) {
newNameField += newNames[k] + "\n";
}
return newNameField;
}
}
}
var re = /\s*\n\s*/;
這是一個新的正則表達式,它搜索的文本模式是按照任何空白字符( \s*)、換行符( \n)和任何
空白字符( \s*)的順序組成的。
re = /(\S+)\s(\S+)/;
7.4 格式化字符串
如何獲得一系列姓名并且將它們轉換為標準的首字母大寫格式.
window.onload = function() {
document.forms[0].onsubmit = validForm;
}

function validForm() {
var allTags = document.forms[0].getElementsByTagName("*");
for (var i=0; i<allTags.length; i++) {
validTag(allTags[i]);
}
return false;
function validTag(thisTag) {
var allClasses = thisTag.className.split(" ");
for (var j=0; j<allClasses.length; j++) {
if (allClasses[j] == "nameList") {
thisTag.value = setNameList(thisTag.value);
}
}
function setNameList(inNameList) {
var newNames = new Array;
var newNameField = "";
var re = /\s*\n\s*/;
var nameList = inNameList.split(re);
re = /^(\S)(\S+)\s(\S)(\S+)$/;
for (var k=0; k<nameList.length; k++) {
if (nameList[k]) {
re.exec(nameList[k]);
newNames[k] = RegExp.$1.toUpperCase() + RegExp.$2.toLowerCase() + " " + RegExp.$3.
? toUpperCase() + RegExp.$4.toLowerCase();
}
}
for (k=0; k<newNames.length; k++) {
newNameField += newNames[k] + "\n";
}
return newNameField;
}
}
}
re = /^(\S)(\S+)\s(\S)(\S+)$/;
這個正則表達式同樣尋找符合“名字、空格、姓氏”次序的姓名,并且將每個姓名分隔成 4 部分:
名字的首字母^(\S)、名字的剩余字母(\S+)、姓氏的首字母(\S)以及姓氏的剩余字母(\S+)$。注意, ^
和 $ 迫使字符串在這兩個位置開始和結束,因為我們不希望漏掉任何東西.
對象的屬性 屬 性意 義
$1
(到$9) 圓括號包圍的子字符串匹配
$_
相當于input
$*
相當于
$&
相當于
$+
相當于
$`
相當于
$’
相當于
指定創建對象原型的函數
全局搜索(使用g修飾符)
不區分大小寫搜索(使用i修飾符)
input
如果沒有傳遞字符串,這就是要搜索的字符串
繼續匹配的起始位置
最后一個匹配的字符串
最后的圓括號包圍的子字符串匹配
最近一個匹配字符串左邊的子字符串
是否跨多行搜索字符串
允許在所有對象中添加屬性
最近一個匹配字符串右邊的子字符串
正則表達式模式本身
對象的方法 方法意 義
(,[, “g” | “i” | “gi”])
對正則表達式進行編譯
exec()
搜索匹配
test()
測試匹配
()
返回一個代表對象的字面值
()
返回一個代表指定對象的字符串
()
返回指定對象的原始值
字符串方法 方法意 義
match(re)
在一個字符串中尋找與一個正則表達式模式( re)的匹配
(re, )
使用正則表達式( re)執行所需的替換
(re)
搜索與正則表達式( re)的匹配
split(re)
根據正則表達式( re)對字符串進行分隔
7.5 對字符串進行格式化和排序
window.onload = function() {
document.forms[0].onsubmit = validForm;
}
function validForm() {
var allTags = document.forms[0].getElementsByTagName("*");
for (var i=0; i<allTags.length; i++) {
validTag(allTags[i]);
}
return false;
function validTag(thisTag) {
var allClasses = thisTag.className.split(" ");
for (var j=0; j<allClasses.length; j++) {
if (allClasses[j] == "nameList") {
thisTag.value = setNameList(thisTag.value);
}
}
function setNameList(inNameList) {
var newNames = new Array;
var newNameField = "";
var re = /\s*\n\s*/;
var nameList = inNameList.split(re);
re = /^(\S)(\S+)\s(\S)(\S+)$/;
for (var k=0; k<nameList.length; k++) {
if (nameList[k]) {
re.exec(nameList[k]);
newNames[k] = RegExp.$3.toUpperCase() + RegExp.$4.toLowerCase() + ", " + RegExp.$1.
? toUpperCase() + RegExp.$2.toLowerCase();
}
}
newNames.sort();
for (k=0; k<newNames.length; k++) {
newNameField += newNames[k] + "\n";
}
return newNameField;
}
}
}
.sort();
7.6 對字符串進行格式化和驗證
最終結果要么是一個經過格式化的電話號碼,要么是輸入框變成紅色,標簽變成紅色、粗體。
window.onload = function() {
document.forms[0].onsubmit = validForm;
}
function validForm() {
var allTags = document.forms[0].getElementsByTagName("*");
for (var i=0; i<allTags.length; i++) {
validTag(allTags[i]);
}
return false;
function validTag(thisTag) {
var outClass = "";
var allClasses = thisTag.className.split(" ");
for (var j=0; j<allClasses.length; j++) {
outClass += validBasedOnClass(allClasses[j]) + " ";
}
thisTag.className = outClass;
if (outClass.indexOf("invalid") > -1) {
invalidLabel(thisTag.parentNode);
thisTag.focus();
if (thisTag.nodeName == "INPUT") {
thisTag.select();
}
}

function validBasedOnClass(thisClass) {
var classBack = "";
switch(thisClass) {
case "":
case "invalid":
break;
case "phone":
if (!validPhone(thisTag.value)) {
classBack = "invalid ";
}
default:
classBack += thisClass;
}
return classBack;
}
function validPhone(phoneNum) {
var re = /^\(?(\d{3})\)?[\.\-\/]?(\d{3})[\.\-\/ ]?(\d{4})$/;
var phoneArray = re.exec(phoneNum);
if (phoneArray) {
document.getElementById("phoneField").value = "(" + phoneArray[1] + ") " + phoneArray[2]
? + "-" + phoneArray[3];
return true;
}
return false;
}
function invalidLabel(parentTag) {
if (parentTag.nodeName == "LABEL") {
parentTag.className += "invalid";
}
}
}
}
var re = /^(?(\d{3}))?[.-/ ]?(\d{3})[.-/ ]?(\d{4})$/;
這個正則表達式尋找這樣的字符串:
? 有一個可選的左圓括號(?
? 有 3 個數字(\d{3})
? 有一個可選的右圓括號)?
? 有一個可選的點號、連字符、正斜杠或空格[.-/ ]?
? 有 3 個數字(\d{3})
? 有一個可選的點號、連字符、正斜杠或空格[.-/ ]?
? 有 4 個數字(\d{4})
這個模式指定了字符串的開頭和結尾qq輸入法完成字符串,所以如果有額外的字符,字符串就不匹配。如果找到三位
的地區編碼數字、三位的前綴數字和四位的后綴數字,就分別保存它們
7.7 使用正則表達式替換元素
window.onload = rolloverInit;
function rolloverInit() {
for (var i=0; i<document.images.length;i++) {
if (document.images[i].parentNode.tagName.toLowerCase() == "a") {
setupRollover(document.images[i]);
}
}
}
function setupRollover(theImage) {
var re = /\s*_off\s*/;
theImage.outImage = new Image();
theImage.outImage.src = theImage.src;
theImage.onmouseout = function() {
this.src = this.outImage.src;
}
theImage.overImage = new Image();
theImage.overImage.src = theImage.src.replace(re,"_on");
theImage.onmouseover = function() {
this.src = this.overImage.src;
}
theImage.clickImage = new Image();
theImage.clickImage.src = theImage.src.replace(re,"_click");
theImage.onclick = function() {
this.src = this.clickImage.src;
}
theImage.parentNode.childImg = theImage;
theImage.parentNode.onblur = function() {
this.childImg.src = this.childImg.outImage.src;
}
theImage.parentNode.onfocus = function() {
this.childImg.src = this.childImg.overImage.src;
}
}
var re = /\s*_off\s*/;
這一行設置一個新的正則表達式模式,它在字符串中的任何地方尋找文本_off。
..src = .src.(re,“_on”);
這一行是 ..src =“/”+ .id + “_on.gif”;。新的代碼使用 re 模式查找特殊的字符串,如果找到,就替換它。本例中我們搜索字符串中的_off,并把它替換為_on。這樣我們就不必為在圖像上設置 id 屬性費心了,根本不需要 id 了。