击右上方红色按钮关注“web秀”,让你真正秀起来
以往我们只是习惯于通过数组下标来访问正则匹配到的分组,但分组达到4、5个时,标识起来就会非常麻烦。V8早已实现了正则命名分组提案,只是我们很少使用,本文将介绍JS的正则命名分组。
JavaScript 正则命名分组
假设要使用正则匹配一个日期的年月日,以往我们会这样做:
const RE_DATE = /(\d{4})-(\d{2})-(\d{2})/; const matchObj = RE_DATE.exec('1999-12-31'); const year = matchObj[1]; // 1999 const month = matchObj[2]; // 12 const day = matchObj[3]; // 31
这里有几个缺点:
所有这些问题,都可以通过正则命名分组来解决。
现在你只需要给分组里面一个命名标识即可:
(?<year>\d{4})
这里,我们用变量year标记了上一个捕获组#1。 该名称必须是合法的JavaScript标识符。 匹配后,您可以通过matchObj.groups.year访问捕获的字符串。
让我们通过命名分组重写前面的代码:
const RE_DATE = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/; const matchObj = RE_DATE.exec('1999-12-31'); const year = matchObj.groups.year; // 1999 const month = matchObj.groups.month; // 12 const day = matchObj.groups.day; // 31
如果正则里面有了命名分组,那么匹配结果会多了一个groups 的属性,这个属性中包含了一切命名分组的捕获结果。配合上解构大法使用又是一股清流:
const {groups: {day, year}} = RE_DATE.exec('1999-12-31'); console.log(year); // 1999 console.log(day); // 31
当然,即使你使用了命名分组,那么返回的结果还可以通过以往的数组下标方式访问:
const year2 = matchObj[1]; // 1999 const month2 = matchObj[2]; // 12 const day2 = matchObj[3]; // 31
命名分组具有以下优点:
反向引用命名分组\k<name> 看下面这个匹配重复单词的例子:
const RE_TWICE = /^(?<word>[a-z]+)!\k<word>$/; RE_TWICE.test('abc!abc'); // true RE_TWICE.test('abc!ab'); // false
同时也可以使用以往的反向引用方式:
const RE_TWICE = /^(?<word>[a-z]+)!\1$/; RE_TWICE.test('abc!abc'); // true RE_TWICE.test('abc!ab'); // false
字符串方法replace()以两种方式支持命名分组:
方式一
const RE_DATE = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/; console.log('1999-12-31'.replace(RE_DATE, '$<month>/$<day>/$<year>')); // 12/31/1999
如果replace不一定是直接返回新的拼接字符串,那么可以看看下面的办法:
方式二
const RE_DATE = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/; console.log('1999-12-31'.replace( RE_DATE, (g, y, m, d, offset, input, {year, month, day}) => month+'/'+day+'/'+year)); // 12/31/1999
看看这replace的callback形参密密麻麻看得心慌慌,很多都用不上,那么我们看看更简单的写法:
console.log('1999-12-31'.replace(RE_DATE, (...args) => { const {year, month, day} = args.slice(-1)[0]; return month+'/'+day+'/'+year; })); // 12/31/1999
这里配合上spread operator直取最后一个参数,再接上一个解构大法,结果又是一股清流。
如果可选的命名组不被匹配,则其属性值被设置为undefined,但key是仍存在:
const RE_OPT_A = /^(?<as>a+)?$/; const matchObj = RE_OPT_A.exec(''); // We have a match: console.log(matchObj[0] === ''); // true // Group <as> didn’t match anything: console.log(matchObj.groups.as === undefined); // true // But property as exists: console.log('as' in matchObj.groups); // true
分组名不能有重复项:
/(?<foo>a)(?<foo>b)/ // SyntaxError: Duplicate capture group name
反向引用一个不存在的分组名:
/\k<foo>/u // SyntaxError: Invalid named capture referenced /\k<foo>/.test("k<foo>") // true, 非 Unicode 下为了向后兼容,k 前面的 \ 会被丢弃
在 reaplce() 方法的替换字符串中引用一个不存在的分组:
"abc".replace(/(?<foo>.*)/, "$<bar>") // SyntaxError: Invalid replacement string "abc".replace(/(.*)/, "$<bar>") // "$<bar>",不包含命名分组时会向后兼容
Chrome60 已支持命名分组 通过babel插件处理兼容问题 babel-plugin-transform-modern-regexp
喜欢小编的点击关注,了解更多知识!
avaScript复选框的分组单选实现
近期在制作MVC实例教学课件中,选择使用了在线考试作为题材进行页面的设计,在线考试主要提供单项选择题,用户点击选择项之后提交服务器端。页面布局时使用了复选按钮进行了选项的设置。本文主要讨论分组复选框模拟实现单选功能。
本例设计使用复选按钮模拟单选按钮主要原因是出于页面的美观。考试页面需要将复选按钮按照题目进行分组,并且针对同一题目只允许选择一个,即模拟实现单选功能。设计页面效果如下图:
考试页面设计效果
考试页面设计效果如上图,按照题目编号分组后实现单选功能。操作动画演示如下图:
动态实现效果展示
使用复选框模拟分组单选按钮设计及实现效果描述如上所示,其实现主要需要借助JavaScript前端交互脚本技术。具体实现思路描述如下:
1、获取被点击复选框编号
获取复选框被点击的编号id主要目的是需要通过编号判断当前复选框属于哪一个分组。进而确定第几道题的第几个选项被点击。
2、获取被点击复选框同组复选框编号
在获取当前点击复选框之后可以通过取余数运算获取余数。设计每个题目必须具有四个选项。通过%4进行取余数。根据余数获取本组其他复选框的ID值。如余数为0,表示当前被点击的是本组最后一个复选框。
3、设置本组其他复选框为未选中状态
在获取本组其他复选框之后,可以进一步通过JavaScript文档对象模型的getElementById()方法获取每一个复选框,并设置其checked属性值为false,表示未选中。
在明确基本实现思路之后可以进行前端HTML页面的设计及JavaScript的编码操作实现等。按照设计思路,需要将试题中出现的所有复选框都设置ID属性。且ID属性需要按照从 1递增进行设置。设计Name属性用于实现分组,即同一题目四个选项对应的复选框Name相同。前端HTML代码描述如下:
input标记及属性设置
input标记及属性设置描述如上图所示,设置id用于标志每一个复选框,设计name标志分组,设计onclick事件用于接受模拟单选操作。
本例设计函数setValue()用于实现处理模拟单选操作,该函数传递标志自身的this。在接收到this之后可以通过它获取对应的id值,并进行进一步处理。基本操作步骤如下:
1、var eid=this.id;
获取当前点击复选框对应的id值并存储变量eid中。
2、var i=eid%4
取余数判断当前复选框在所属组中的位次。
3、var el=new Array(3)
.结构标记:作用就是为了提升标记的语义性,每个结构有每个不同的标记。
1.头部标记:<header></header>,用于定义页面的页眉,最上面的内容。等同于<div id="header"></div>,作用一样。就是相当于一个容器,装其他的元素。
2.导航标记:<nav></nav>,用于定义页面的导航链接部分。等同于<div id="nav"></div>
例如可以这样写导航:
<nav>
<ul>
<li></li>
</ul>
</nav>
3.主体标记:<section></section>作用:定义页面主体内容中的小节,现在section可以表示整个页面的主体内容等同于<div id="main"></div>
4.<article></article>作用:用于描述文本性较强,或者艺术气息较强的内容。一般情况下,论坛中的帖子信息,报纸信息,博客或微博中的条目信息。用户回复信息,有限考虑放在article中
5.<footer></footer>定义页面中或某个区域中的脚注信息,页面最底部的信息。
6.边栏:<aside></aside>定义页面侧边栏,靠边的信息
以上结构标记为的就是独立定义结构,替代div。
表单
表单的作用:显示,收集信息,并且将信息提交给服务器
(在注册,登陆的时候,网页就会提供一些供用户填写的表单,表单元素会把填写的信息提交服务器进行处理 )
表单包含两组内容
1.表单元素<form>
<form></form>
注意:使用表单控件提交数据时,表单不能省略
属性:
1.action:后台处理程序的地址(服务器端工程师提供),默认会提交给本页。
2.method:方式,表单的提交方式。不同的提交方式约束的内容不一样。
常用取值:2个
get:
1.显示提交数据,会将提交信息显示在地址栏上面,安全性不高,又叫显示提交
2.大小限制,最大支持到2kb的提交。
3.如果不设置method属性,默认就是get方式提交(显示提交,最大2kb)
4.使用场合:向服务器索取数据时,优先使用get
post:
1.隐式提交数据,不会将提交的信息显示在地址栏上,安全性较高,所有有关密码的信息提交时,必须用post
2.post没有大小限制。
3.使用场合:安全性要求较高的页面,传递数据量较大的时候
3.enctype
作用:设置对表单中提交的数据的编码方式,规范哪些数据可以提交给服务器
取值:
1.application/x-www-form-urlencoded,默认值,可以将普通的文本,特殊的字符,一起提交给服务器。
2.multipart/form-date,允许将表单中的文件,传递给服务器,普通文本不能直接传递。
3.text/plain,只能将普通文本传递给服务器,特殊字符不允许。
4.id
5.name
2.表单控件
什么是表单控件
包含在表单中的元素,具备可视化外观,并且可以接受用户输入的数据。
分类
1.input元素
2.textare文本域
3.select和option选项框
一.input元素,主要作用就是收集用户信息
语法:<input>
属性:
type,根据不同的类型值可以创建不同的输入控件,用户名,密码,按钮形式的
value,控件的值,提交给服务器的数据。
name,控件的名称。必须设置,否则无法提交,服务器主要根据name这个控件的名称,来获取value
disabled,禁用控件,该属性可以没有值。
1.文本框和密码框
文本框:<input type="text">
允许用户输入任意字符的数据,明文显示
密码框:<input type="password">
允许用户输入任意字符的数据,密文显示
属性:
maxlength:限制输入的字符数
readonly:只读,无需给值
value:控件值,同时也可以设置控件
注意:input元素下,如果不写type值,或者type值写错时,都默认为文本框。
单选框和复选框
1.单选框:<input type="radio">
属性:
1.name:定义名称并且实现控件分组,一组内的元素才能实现单选
2.value:控件值
3.checked:设置默认被选中,不需要值
2.复选框
<input type="checkbox">
属性:name:定义名称并且分组,便于服务器获取
3.按钮
1.提交按钮,功能固定化,负责将数据提交给服务器
<input type="submit">
2.重置按钮,功能固定化,负责将表单控件恢复到初始化的状态
<input type="reset">
3.普通按钮,没有固定功能,由开发者通过js来设置。
<input type="button">
value:显示在按钮上的文本
name:名称(可写可不写)
4.非input标签的按钮
<button></button>
<button type="button">普通按钮</button>
属性:type
5.隐藏域和文件选择框
1。隐藏域,不想让用户看见,但是又要提交到服务器的数据,可以放在隐藏域中
例如:隐藏用户id
type="hidden"
<input tpe="hidden">
属性:
name
value
6.文件选择框
提供一个基础控件,允许用户选择本机的文件上传到服务器
type="file"
<input type="file">
属性:name value
注意:
表单的method(提交方式)属性值必须为post
表单的enctype编码必须为multipart/form-date
更多知识关注小编,或者百度网络营销师钟震,钟震讲网络营销。会有很多相关知识,公众号网络营销师钟震,以后每天都会分享web前端,淘宝运营,竞价,网站建设和优化,社媒方面的知识。与大家共同进步。希望对您有一点点帮助,喜欢记得关注公众号。
*请认真填写需求信息,我们会在24小时内与您取得联系。