实训11 正则表达式

HTML 讲解

html 复制代码
<!doctype html> <!-- 声明文档类型为HTML5 -->
<html> <!-- HTML文档的根元素 -->
<head> <!-- 文档头部,包含元数据和引用的外部资源 -->
<meta charset="utf-8"> <!-- 声明字符编码为UTF-8 -->
<title>使用正则表达式校验表单数据的有效性</title> <!-- 页面标题 -->
<style> <!-- 内嵌CSS样式 -->
table{ /* 表格样式 */
	width:360px; /* 设置表格宽度 */
	border-collapse:collapse; /* 合并表格边框 */
	border:1px solid #000; /* 设置表格边框 */
}

td{ /* 单元格样式 */
	font:14px/18px "微软雅黑"; /* 设置字体样式 */
	padding:4px 8px; /* 设置内边距 */
	border:1px solid #000; /* 设置单元格边框 */
}

</style>
<script type="text/javascript" src="js/validation.js"></script> <!-- 引入外部JavaScript文件 -->
</head>
<body> <!-- 文档主体内容 -->
  <form action="welcome.html"> <!-- 表单定义,提交到welcome.html -->
    <table id="tbl"> <!-- 创建表格 -->
    <tr><td>用户名</td><td><input type="text" name="username" 
id="username"/></td></tr> <!-- 用户名输入行 -->
    <tr><td>密 码</td><td><input type="password" name="psw" id="psw"/></td></tr> <!-- 密码输入行 -->
    <tr><td>身份证号</td><td><input type="text" name="IDC" id="idc"/></td></tr> <!-- 身份证输入行 -->
    <tr><td>email</td><td><input type="text" name="email" id="email"/></td></tr> <!-- 邮箱输入行 -->
    <tr><td>家庭电话</td><td><input type="text" name="tel" id="tel"/></td></tr> <!-- 电话输入行 -->
    <tr><td>手 机</td><td><input type="text" name="mobil" id="mobil"/></td></tr> <!-- 手机输入行 -->
    <tr><td>通讯地址</td><td><input type="text" name="address" 
id="address"/></td></tr> <!-- 地址输入行 -->
    <tr><td>邮 编</td><td><input type="text" name="zip" id="zip"/></td></tr> <!-- 邮编输入行 -->
    <tr><td colspan="2"><input type="submit" value="提交" id='btn'></td></tr> <!-- 提交按钮,横跨两列 -->
    </table>
  </form>
</body>
</html>
  1. "为什么密码字段要使用type='password'?"

    标准答案:

    安全性:用星号或圆点隐藏输入内容,防止旁人窥视

    用户体验:明确向用户表明这是敏感信息字段

    浏览器功能:触发浏览器的密码管理功能(保存、自动填充)

    移动设备优化:在移动端会调出适合密码输入的虚拟键盘

    扩展讲解:

    "虽然前端显示隐藏了,但传输到服务器时仍然是明文,所以还需要后端加密处理。在实际开发中,我们通常会对密码进行哈希加密后再存储。"

  2. "表格布局和div布局各有什么优缺点?"

    表格布局优点:

    简单直观,容易实现对齐

    兼容性好,在老浏览器中表现一致

    适合真正的表格数据展示

    表格布局缺点:

    语义不准确:表格应用于数据,而非布局

    灵活性差:难以实现响应式设计

    代码冗余:需要大量tr、td标签

    加载性能:需要整个表格加载完才能渲染

    可访问性差:屏幕阅读器会按表格语义阅读

div+CSS布局优点:

语义明确,结构清晰

灵活性强,易于实现响应式

代码简洁,易于维护

加载性能更好

SEO友好,可访问性佳

javascript 复制代码
window.onload = function(){ // 页面加载完成后执行
	var oBtn = document.getElementById('btn'); // 获取提交按钮元素
	oBtn.onclick = function(){ // 为提交按钮添加点击事件处理函数
		var flag = true; // 验证标志,初始为true表示通过验证
		var username = document.getElementById("username"); // 获取用户名输入框
		var password = document.getElementById("psw"); // 获取密码输入框
		var idc = document.getElementById("idc"); // 获取身份证输入框
		var email = document.getElementById("email"); // 获取邮箱输入框
		var tel = document.getElementById("tel"); // 获取电话输入框
		var mobil = document.getElementById("mobil"); // 获取手机输入框
		var address = document.getElementById("address"); // 获取地址输入框
		var zip = document.getElementById("zip"); // 获取邮编输入框
		var url = document.getElementById("url"); // 获取URL输入框(但在HTML中不存在)
		
		//用户名第一个字符为字母,其他字符可以是字母、数字、下划线等,且长度为3~10个字符
		var pname = /^[a-zA-Z]\w{2,9}$/;  	
		
		//密码可以是任何非空白字符,长度为6~15个字符
		var ppsw = /\S{6,15}/;
		
		//身份证号为15位或18位数字,或17位数字后面跟一个x或X  
		var pidc = /^\d{15}$|^\d{17}[\d|x|X]$/;  
	      
		//email包含@,且其左、右两边包含任意多个单词字符,后面则包含至少一个包含.和2~3个单词字符的子串
		var pemail = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/; 
		 
		//家庭电话格式为:xxx-xxxxxxx 或 xxxx-xxxxxxxx,其中"x"表示一个数字
		var ptel = /^\d{3,4}-\d{7,8}$/;
		
		//手机为11位数字,且第二数字只能为3、4、5、7或8
		var pmobil = /^1[3|4|5|7|8]\d{9}$/;
		
		//地址可以是任何非空白字符,长度为6~30个字符
		var paddress = /\S{6,30}/;
		
		//邮编为6位数字,其中第1位为1~9中的某个数字,后5位为0~9中的5个数字
		var pzip = /^[1-9][0-9]\d{4}$/; 
		
		// 验证用户名
		if(!pname.test(username.value)){
			flag = false; // 验证失败,设置标志为false
			alert("用户名第一个字符为字母,长度为3~10个字符");
		}
		
		// 验证密码
		if(!ppsw.test(password.value)){
			flag = false;
			alert("密码长度为6~15个非空白字符");
		}
		
		// 验证身份证号
		if(!pidc.test(idc.value)){
			flag = false;
			alert("身份证号为15位或18位,请输入正确的身份证号");
		}
		
		// 验证邮箱
		if(!pemail.test(email.value)){
			flag = false;
			alert("email包含@以及至少一个包含.和2~3个单词字符的子串");
		}
		
		// 验证家庭电话
		if(!ptel.test(tel.value)){
			flag = false;
			alert("家庭电话的格式为xxx/xxxx-xxxxxxx/xxxxxxxx");
		}
		
		// 验证手机
		if(!pmobil.test(mobil.value)){
			flag = false;
			alert("手机手机为11位数字,且第二数字只能为3、4、5、7或8");
		}
		
		// 验证地址
		if(!paddress.test(address.value)){
			flag = false;
			alert("地址长度为6~30个字符");
		}
		
		// 验证邮编
		if(!pzip.test(zip.value)){
			flag = false;
			alert("邮编为6位数字,其中第1位为1~9中的某个数字,后5位为0~9中的5个数字");
		}
		
		//当flag的值为false时,取消提交按钮的默认提交行为
		if(!flag){
			return false; // 阻止表单提交
		}
		// 如果flag为true,表单会正常提交
	};
};

基础理解类问题

  1. 代码结构理解
    Q1: window.onload 的作用是什么?为什么需要它?
    答案: 它确保页面完全加载后再执行JavaScript代码,避免在DOM元素尚未加载时尝试获取元素导致的错误。

Q2: 变量 flag 在代码中起什么作用?

答案: 它是一个验证标志,初始为true,任何一项验证失败就设为false,最终决定是否阻止表单提交。

Q3: 代码中 return false 的作用是什么?

答案: 阻止表单的默认提交行为,当验证失败时不让表单提交到服务器。

  1. 正则表达式理解
    Q4: 用户名正则 /[1](#1)\w{2,9}$/ 中的 \w 表示什么?
    答案: \w 匹配任何单词字符,等价于 a-zA-Z0-9_

Q5: 身份证正则中 | 符号的作用是什么?

答案: 表示"或"的关系,匹配15位数字或18位数字(最后一位可以是数字或X)。

Q6: 邮箱正则中 (.-?\w+)* 这部分如何理解?

答案: 表示邮箱本地部分可以有零个或多个由点或连字符分隔的单词字符组。

应用分析类问题

  1. 代码改进

Q7: 这段代码在用户体验方面有什么可以改进的地方?

答案:

可以改为实时验证而不是点击提交时验证

错误提示可以更友好,如显示在输入框旁边而不是alert

可以添加密码强度提示

Q8: 这段代码中有一个潜在问题,你发现了吗?

答案: 代码中声明了 var url = document.getElementById("url"),但HTML中并没有id为"url"的元素,这可能导致错误。

Q9: 家庭电话的注释描述与实际正则表达式不符,你发现了吗?

答案: 注释说格式是"xxx/xxxx-xxxxxxx/xxxxxxxx",但正则表达式是 /^\d{3,4}-\d{7,8}$/,实际要求是"xxx-xxxxxxx"或"xxxx-xxxxxxxx"格式。

  1. 扩展思考
    Q10: 这段代码只做了前端验证,为什么还需要后端验证?
    答案: 前端验证可以被绕过(如禁用JavaScript),后端验证是确保数据安全的最后一道防线。

Q11: 密码验证使用 \S{6,15} 有什么安全隐患?

答案: 这个正则太宽松,没有要求包含字母、数字和特殊字符的组合,可能导致弱密码。

Q12: 如何修改代码使其在验证失败时聚焦到第一个错误的输入框?

答案: 可以在每个验证失败的地方添加 username.focus() 等代码,并确保只聚焦第一个错误项。


  1. a-zA-Z ↩︎
相关推荐
Patrick在香港16 小时前
Python正则表达式实战:解析和验证香港身份证、车牌、电话格式
开发语言·python·正则表达式
吴声子夜歌3 天前
正则指引——Ruby
开发语言·正则表达式·ruby
吴声子夜歌3 天前
正则指引——Golang
开发语言·golang·正则表达式
吴声子夜歌4 天前
正则指引——PHP
开发语言·正则表达式·php
吴声子夜歌5 天前
正则指引——断言
正则表达式
吴声子夜歌6 天前
正则指引——匹配原理
java·正则表达式
吴声子夜歌7 天前
正则表达式——环视
开发语言·正则表达式
吴声子夜歌7 天前
正则表达式——边界
正则表达式
营养充电站8 天前
C++23 新特性在 CLion 中的实战体验
macos·docker·jupyter·正则表达式