JavaScript 学习笔记 - 7 表单和正则表达式

正则表达式( regular expression,常常缩写为 RegExp)是一种用特殊符号编写的模式,描述一个
或多个文本字符串。使用正则表达式匹配文本的模式,这样脚本就可以轻松地识别和操纵文本。与算
术表达式一样,创建正则表达式也要使用操作符,但是在这种情况下使用的是操作文本(而不是数字)
的操作符。

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">&nbsp;<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})+$/;

  正则表达式总是以斜杠( /)开头和结尾(当然,仍然有一个分号,表示 JavaScript 代码行结束,
但分号不是正则表达式的一部分)。斜杠之间的所有内容都是正则表达式的组成部分。
  脱字符( ^)表示我们要使用这个表达式检查以特定的字符串开头的字符串。如果去掉脱字符,
那么即使字符串开头有一堆“垃圾字符”,电子邮件地址也可能被认为是有效的。
  表达式\w 表示任意单一字符,包括 a~ z、 A~ Z、 0~ 9 和下划线。电子邮件地址必须以这些字符
之一开头。
  加号+表示我们要寻找前面条目的一次或多次出现。在这个示例中,电子邮件地址必须以字符 a~ z、
A~ Z、 0~ 9 或下划线的任意组合开头。
  左圆括号(表示一个组。这意味着后面将要引用圆括号中的所有内容,所以现在将它们放在一个
组中。
  方括号[]用来表示可以出现在其中的任意一个字符。在这个示例中,方括号内包含字符.-。我
们希望允许用户输入点号或连字符,但是点号对于正则表达式有特殊意义,所以需要在它前面加上反
斜杠\,这表示我们指的实际上是点号本身,而不是它的特殊意义。在特殊字符前面使用反斜杠称为
“对字符转义”。因为有方括号,输入的字符串在这个位置可以有一个点号或一个连字符,但是两者不
能同时存在。注意,连字符不代表任何特殊字符,所以不用加反斜杠。
  问号?表示前面的条目可以不出现或者出现一次。所以,在电子邮件地址的第一部分(在@前面的
部分)中可以有一个点号或一个连字符,也可以没有。
在?后面,再次使用\w+,这表示点号或连字符后面必须有其他一些字符。
右圆括号)表示这个组结束了。在此之后是一个星号,表示前面的条目(在这个示例中,指圆括
号中的所有内容)可以不出现或者出现多次。所以如果 dori 是有效的电子邮件前缀, testing-testing-1-2-3
也是。
  @字符仅仅代表它本身,没有任何其他意义,这个字符位于电子邮件地址前缀和域名之间。
再次使用\w+,这表示域名必须以一个或多个 a~ z、 A~ Z、 0~ 9 或下划线字符开头。在此之后同
样是([.-]?\w+)*,表示电子邮件地址的后缀中允许有点号或连字符。
然后,在一对圆括号中建立另一个组: .\w{2,3},表示我们希望找到一个点号,后面跟着一些字
符。在这个示例中,花括号中的数字表示前面的条目(本例中是\w,表示字母、数字或下划线)可以
出现 2 次或 3 次。在这个组的右圆括号后面是一个+,也表示前面的条目(这个组)必须出现一次或
多次。这会匹配.com 或.edu 之类的,也与 ox.ac.uk 匹配。
  最后,正则表达式的末尾是一个美元符号$,表示匹配的字符串必须在这里结束。这使脚本能够
拒绝那些开头正确,但是在末尾包含垃圾字符的电子邮件地址。斜杠结束正则表达式。分号和原来一
样结束 JavaScript 语句。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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 提取字符串

我们获得一系列输入的姓名,其中名字在前,姓氏在后,然后交换名和姓的次序.

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;
}
}
}
  1. var re = /\s*\n\s*/;
    这是一个新的正则表达式,它搜索的文本模式是按照任何空白字符( \s*)、换行符( \n)和任何
    空白字符( \s*)的顺序组成的。

  2. 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;
}
}
}
  1. re = /^(\S)(\S+)\s(\S)(\S+)$/;

这个正则表达式同样寻找符合“名字、空格、姓氏”次序的姓名,并且将每个姓名分隔成 4 部分:
名字的首字母^(\S)、名字的剩余字母(\S+)、姓氏的首字母(\S)以及姓氏的剩余字母(\S+)$。注意, ^
和 $ 迫使字符串在这两个位置开始和结束,因为我们不希望漏掉任何东西.
在这里插入图片描述

RegExp对象的属性
属 性意 义
$1(到$9) 圆括号包围的子字符串匹配
$_相当于input
$*相当于multiline
$&相当于lastMatch
$+相当于lastParen
$`相当于leftContext
$’相当于rightContext
constructor指定创建对象原型的函数
global全局搜索(使用g修饰符)
ignoreCase不区分大小写搜索(使用i修饰符)
input如果没有传递字符串,这就是要搜索的字符串
lastIndex继续匹配的起始位置
lastMatch最后一个匹配的字符串
lastParen最后的圆括号包围的子字符串匹配
leftContext最近一个匹配字符串左边的子字符串
multiline是否跨多行搜索字符串
prototype允许在所有对象中添加属性
rightContext最近一个匹配字符串右边的子字符串
source正则表达式模式本身
RegExp对象的方法
方法意 义
compile(pattern,[, “g” | “i” | “gi”])对正则表达式进行编译
exec(string)搜索匹配
test(string)测试匹配
toSource()返回一个代表对象的字面值
toString()返回一个代表指定对象的字符串
valueOf()返回指定对象的原始值
字符串方法
方法意 义
match(re)在一个字符串中寻找与一个正则表达式模式( re)的匹配
replace(re, replaceStr)使用正则表达式( re)执行所需的替换
search(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;
}
}
}

newNames.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";
}
}
}
}
  1. var re = /^(?(\d{3}))?[.-/ ]?(\d{3})[.-/ ]?(\d{4})$/;
    这个正则表达式寻找这样的字符串:
     有一个可选的左圆括号(?
     有 3 个数字(\d{3})
     有一个可选的右圆括号)?
     有一个可选的点号、连字符、正斜杠或空格[.-/ ]?
     有 3 个数字(\d{3})
     有一个可选的点号、连字符、正斜杠或空格[.-/ ]?
     有 4 个数字(\d{4})
    这个模式指定了字符串的开头和结尾,所以如果有额外的字符,字符串就不匹配。如果找到三位
    的地区编码数字、三位的前缀数字和四位的后缀数字,就分别保存它们

在这里插入图片描述

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;
}
}
  1. var re = /\s*_off\s*/;
    这一行设置一个新的正则表达式模式,它在字符串中的任何地方寻找文本_off。

  2. theImage.overImage.src = theImage.src.replace(re,“_on”);
    这一行是 theImage.overImage.src =“images/”+ theImage.id + “_on.gif”;。新的代码使用 re 模式查找特殊的字符串,如果找到,就替换它。本例中我们搜索字符串中的_off,并把它替换为_on。这样我们就不必为在图像上设置 id 属性费心了,根本不需要 id 了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值