字符串是重要是數據類型之一,正則表達式賦予開發者更多操做字符串的能力。該篇文章主要介紹ES6中新添一些字符串特性、方法以及正則表達式。
一、字符串、編碼單元的概念
字符串指的由一個個單個字符拼接而成,如"test123",表示1個字符串,該字符串包括7個字符;
16位(bit)的0、1編碼組成一個編碼單元。
二、length屬性
字符串的length屬性只對字符串有效,length返回的是字符串編碼單元的數量。對於32位編碼表示的字符其length值爲2。html
let num=123; let b=null; let str="test123"; console.log(num.length); //undefined console.log(b.length); //報錯 console.log(str.length); //7 let text="𠯿"; console.log(text.length); //2
三、超過16位編碼的字符表示
當字符編碼超過16位後,好比日語,採用代理對錶示該字符,即採用32位編碼表示該字符。此時須要採用{}識別超出(uffff)範圍的編碼正則表達式
console.log(\u7f16); //"編" console.log(\u{20bff}); //"𠯿"
四、charAt()、charCodeAt()、codePointAt()
charAt(0)表示獲取16位編碼表示的單個字符
charCodeAt(0)表示獲取單個字符的十六進制編碼,若是字符爲32爲編碼,則獲取的是前16位編碼單元對應的數值。
codePointAt(0)表示獲取單個字符的十六進制編碼,若是字符爲32爲編碼,則獲取的是32位編碼單元對應的數值。shell
若是字符爲16位編碼,則charCodeAt()方法和codePointAt()方法返回的值一致,都是16位編碼單元對應的數值。瀏覽器
var a="編"; //16位編碼表示的字符 console.log(a.charAt(0)); //"編" console.log(a.charCodeAt(0)); //"32534" console.log(a.codePointAt(0)); //"32534" var b="𠯿"; //32位編碼表示的字符 console.log(b.charAt(0)); //沒法打印出該字符 console.log(b.charCodeAt(0)); //"55362" console.log(b.charCodeAt(1)); //"57343" console.log(b.codePointAt(0)); //"134143"
## 如何判斷一個字符采用 16bit or 32bit 編碼? ## var a="𠯿"; if(a.codePointAt(0)>0xffff){ //32bit編碼 }else{ //16bit編碼 }
五、normalize()方法
若是須要對字符串進行排序或比較操做時,最好對字符串先進行標準化處理。如開發國際化應用時,一個字符(e.g:日語)採用兩個16位編碼表示。若是不標準化直接處理,則有可能出錯。但在平時開發中若沒有考慮過Unicode標準化問題,則沒必要考慮採用該方法對字符串處理。
再好比表明相同文本的兩個字符串可能包含着不一樣的碼位序列。如"æ"和"ae"能夠互換使用,可是嚴格來說它們不是等效的,但能夠經過normalize()方法標準化。函數
let normalized=values.map(function(text){ return text.normalize(); }); normalized.sort(function(first,second){ if(first<second){ return -1; }else if(first===second){ return 0; }else{ return 1; } })
六、字符串新增方法
endsWith()--在字符串結束部分檢測到指定文本,則返回true,不然返回false
startsWith()--在字符串開始部分檢測到指定文本,則返回true,不然返回false
includes()--在字符串中檢測到指定文本,則返回true,不然返回false
repeat(n)--返回字符串重複n次後的結果
padStart(8,'0')--第一個參數是限制字符串的長度,第二個前面要補的內容
padEnd(8,'0')--第一個參數是限制字符串的長度,第二個後面要補的內容編碼
let str='hello girls'; console.log(str.startsWith("h")); //從索引爲0的位置匹配 console.log(str.startsWith("g",6)); //從索引爲6,即第7個位置開始匹配 console.log(str.endsWith("s")); //默認從最後一個位置向前匹配 console.log(str.endsWith("e",2)); //從索引爲1的位置向前匹配 console.log(str.includes("ls")); //從索引0位置開始匹配 console.log(str.repeat(2)); //"hello girlshello girls" console.log(str.padStart(13,'!')); //"!!hello girls" console.log(str.padEnd(13,'!')); //"hello girls!!"
七、正則表達式
a、u修飾符:當未使用u修飾符時,匹配編碼單元(16bit);使用u修飾符後匹配的是字符。代理
//𠯿佔用兩個編碼單元 /^.$/.test("𠯿"); //false /^.$/u.test("𠯿"); //true //採用try catch()檢測瀏覽器是否支持u try{ var pattern=new RegExp("abc","u"); return true; }catch(error){ return false; }
b、y修飾符:它會影響正則表達式搜索過程當中的sticky屬性,當字符串中開始字符匹配時,它會通知從正則表達式的lastIndex屬性開始進行,若是在指定位置沒能匹配成功,則中止繼續匹配。code
var text="hello1 hello2 hello3", pattern=/hello\d\s?/, result=pattern.exec(text), globalPattern=/hello\d\s?/g, globalResult=globalPattern.exec(text), stickyPattern=/hello\d\s?/y, stickyResult=stickyPattern.exec(text); console.log(result,pattern.lastIndex); //[ 'hello1 ', index: 0, input: 'hello1 hello2 hello3' ] 0 console.log(globalResult,globalPattern.lastIndex); //[ 'hello1 ', index: 0, input: 'hello1 hello2 hello3' ] 7 console.log(stickyResult,stickyPattern.lastIndex); //[ 'hello1 ', index: 0, input: 'hello1 hello2 hello3' ] 7 result=pattern.exec(text); //從索引0開始匹配 globalResult=globalPattern.exec(text); //從索引7開始匹配 stickyResult=stickyPattern.exec(text); //從索引7開始匹配 console.log(result,pattern.lastIndex); //[ 'hello1 ', index: 0, input: 'hello1 hello2 hello3' ] 0 console.log(globalResult,globalPattern.lastIndex); //[ 'hello2 ', index: 7, input: 'hello1 hello2 hello3' ] 14 console.log(stickyResult,stickyPattern.lastIndex); //[ 'hello2 ', index: 7, input: 'hello1 hello2 hello3' ] 14 pattern.lastIndex=1; globalPattern.lastIndex=1; stickyPattern.lastIndex=1; result=pattern.exec(text); //忽略對lastIndex的修改,從0開始匹配 globalResult=globalPattern.exec(text); //從第二個字符e開始匹配 stickyResult=stickyPattern.exec(text); //從第二個字符e開始匹配 console.log(result,pattern.lastIndex); //[ 'hello1 ', index: 0, input: 'hello1 hello2 hello3' ] 1 console.log(globalResult,globalPattern.lastIndex); //[ 'hello2 ', index: 7, input: 'hello1 hello2 hello3' ] 14 console.log(stickyResult,stickyPattern.lastIndex); //拋出錯誤。因爲從第二個位置匹配不到相應字符串,就此終止,所以結果爲null 0
c、正則表達式的複製
var re1=/ab/i;
var re2=new RegExp(re1,"g"); //rel爲/ab/g
re1與re2無關,改變其中一個並不會影響另外一個。
d、新增正則屬性orm
let re=/ab/g; re.source; //"ab" 表示正則表達式文本 re.flags; //"g" 表示正則表達式修飾符
八、模板字面量
模板字符串提供三方面能力:
a、多行字符串htm
let str=` hello /輸出兩行,而且每行都有縮進 world `
b、字符串佔位符
變量佔位符容許將任何有效的JS表達式嵌入到模板字面量中,並將其結果輸出爲字符串的一部分
let name='nicholas', message=`hello,${ `my name is ${name}` }.`; console.log(message);
c、標籤模板
function passthru(literals,...substitutions){ //literals中保存的有a、第一個佔位符前的空字符串("");b、第1、二個佔位符之間的字符串;c、第二個佔位符後的字符串(".") let result=""; for(let i=0;i<substitutions.length;i++){ result+=literals[i]; result+=substitutions; } return result; } let count=10, price=0.25, message=passthru`${count} items cost $${(count*price).toFixed(2)}.`; console.log(message); //10 items cost $2.50
標籤模板的應用(##注:如下內容轉自http://www.cnblogs.com/xiaohu...,侵刪##):
a、過濾用戶輸入,防止用戶惡意輸入
var message = SaferHTML`<p>${sender} has sent you a message.</p>`; function SaferHTML(templateData) { var s = templateData[0]; for (var i = 1; i < arguments.length; i++) { var arg = String(arguments[i]); // Escape special characters in the substitution. s += arg.replace(/&/g, "&") .replace(/</g, "<") .replace(/>/g, ">"); // Don't escape special characters in the template. s += templateData[i]; } return s; }
上面代碼中,sender變量每每是用戶提供的,通過SaferHTML函數處理,裏面的特殊字符都會被轉義
var sender = '<script>alert("abc")</script>'; // 惡意代碼 var message = SaferHTML`<p>${sender} has sent you a message.</p>`; console.log(message);// <p><script>alert("abc")</script> has sent you a message.</p>
b、標籤模板的另外一個應用,就是多語言轉換(國際化處理)
i18n`Welcome to ${siteName}, you are visitor number ${visitorNumber}!` // "歡迎訪問xxx,您是第xxxx位訪問者!"