整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          JavaScript 正則命名分組

          擊右上方紅色按鈕關注“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
          

          命名分組具有以下優點:

          • 找到分組的“ID”更容易。
          • 匹配的代碼變得自描述性,因為分組的ID描述了捕獲的內容。
          • 如果更改分組的順序,則不必更改匹配的代碼。
          • 分組的名稱也使正則表達式更易于理解,因為您可以直接看到每個組的用途。

          反向引用

          反向引用命名分組\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( )

          字符串方法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前端,淘寶運營,競價,網站建設和優化,社媒方面的知識。與大家共同進步。希望對您有一點點幫助,喜歡記得關注公眾號。


          主站蜘蛛池模板: 一区二区在线视频免费观看| 国产一区二区在线观看app| 国产亚洲一区二区手机在线观看| 精品一区二区91| 国产精品一区二区av| 精品少妇人妻AV一区二区三区 | 国产在线视频一区二区三区| 日韩免费一区二区三区| 日韩精品人妻一区二区中文八零| 伊人久久精品无码麻豆一区| 成人毛片无码一区二区| 亚洲线精品一区二区三区影音先锋| 麻豆aⅴ精品无码一区二区| 成人丝袜激情一区二区 | 日本在线一区二区| 后入内射国产一区二区| 亚洲电影唐人社一区二区| 东京热人妻无码一区二区av| 美女免费视频一区二区| 欧美av色香蕉一区二区蜜桃小说| 一夲道无码人妻精品一区二区| 国产精品美女一区二区| 亚洲综合一区无码精品| 亚洲福利视频一区二区三区| 国产精品一区二区av| 久久福利一区二区| 亚洲国产情侣一区二区三区| 消息称老熟妇乱视频一区二区| 国产在线精品一区二区三区不卡| 内射少妇一区27P| 最美女人体内射精一区二区| 久久精品国产亚洲一区二区三区| 一区二区三区四区电影视频在线观看| 无码AV中文一区二区三区| 亚洲码欧美码一区二区三区| 人妻内射一区二区在线视频| 亚洲AV日韩综合一区| 日本精品夜色视频一区二区| 免费视频一区二区| 日本高清一区二区三区| 真实国产乱子伦精品一区二区三区 |