ES6-字符串和正則表達(dá)式


title: ES6-字符串和正則表達(dá)式
date: 2018-01-30 22:15:59
tags: es6


timg.jpg

前言

入行這么久了氢伟,前端學(xué)習(xí)的成本感覺越來越高了,不會(huì)的東西一茬接一茬或粮,在學(xué)校太忽視它导饲,學(xué)的半吊子,現(xiàn)在要努力趕上才行,杭州的天氣變冷了帜消,我也想回家了棠枉,堅(jiān)持,哎嘿泡挺,再上半個(gè)月班就要放假了開心辈讶。(這是從我自己博客移植過來的)

我的博客地址 :http://www.aymfx.cn/,歡迎訪問

引子

這張理解起來比較費(fèi)勁娄猫,慢慢看贱除,慢慢練,天氣比較冷啊,手敲這些好費(fèi)勁

utf-16碼位(基本多文種平面)到輔助平面字符的擴(kuò)展

在ES6之前媳溺, JS 的字符串以 16 位字符編碼(UTF-16)為基礎(chǔ)月幌。每個(gè) 16 位序列(相當(dāng)于2個(gè)字節(jié))是一個(gè)編碼單元(code unit),可簡(jiǎn)稱為碼元悬蔽,用于表示一個(gè)字符扯躺。字符串所有的屬性與方法(如length屬性與charAt() 方法等)都是基于16位序列

最常用的Unicode字符使用16位序列編碼字符,屬于“基本多語種平面”(Basic Multilingual Plane BMP)蝎困,也稱為“零斷面”(plan 0)录语, 是Unicode中的一個(gè)編碼區(qū)段,編碼介于\u0000~\uFFFF之間禾乘。超過這個(gè)范圍的碼位則要?dú)w屬于某個(gè)輔助平面或稱為擴(kuò)展平面(supplementary plane)澎埠,其中的碼位僅用16位就無法表示了 為此,UTF-16引入了代理對(duì)(surrogate pairs)始藕,規(guī)定用兩個(gè)16位編碼來表示一個(gè)碼位蒲稳。這意味著,字符串里的字符有兩種:一種由一個(gè)碼元(共 16 位)來表示BMP字符伍派,另一種用兩個(gè)碼元(共 32 位)來表示輔助平面字符

let text = '?'

console.log(text.length); //2
console.log(/^.$/.test(text)); //false
console.log(text.charAt(0)); //?
console.log(text.charAt(1)); //?
console.log(text.charCodeAt(0)); //55362
console.log(text.charCodeAt(1)); //57271

這個(gè)字?(jí)其實(shí)就是一個(gè)兩個(gè)16位字符組成的字,基于16位字符串的屬性與方法便失效了

codePointAt() 只接受編碼單元的位置而非字符位置作為參數(shù),返回給定位置對(duì)應(yīng)的碼位

let text = 'a?'

console.log(text.charCodeAt(0)); //55362
console.log(text.charCodeAt(1)); //57271
console.log(text.charCodeAt(2)); //57271

console.log(text.codePointAt(0)); //134071
console.log(text.codePointAt(1)); //57271
console.log(text.codePointAt(2)); //57271

通過這個(gè)方法我們可以檢測(cè)字符是不是32位的

function is32Bit(char){
    return char.codePointAt(0) > 0xffff;
    
}

console.log(is32Bit('?')); //ture
console.log(is32Bit('a'));  //false

String.fromCodePoint()通過碼位獲得對(duì)應(yīng)字符

  console.log(String.fromCodePoint(134071)); //?

normalize()

許多歐洲語言有語調(diào)符號(hào)和重音符號(hào)江耀。為了表示它們,Unicode提供了兩種方法诉植。一種是直接提供帶重音符號(hào)的字符决记,比如ǒ(\u01D1)。另一種是提供合成符號(hào)(combining character)倍踪,即原字符與重音符號(hào)的合成系宫,兩個(gè)字符合成一個(gè)字符,比如O(\u004F)和ˇ(\u030C)合成ǒ(\u004F\u030C)建车。
這兩種表示方法扩借,在視覺和語義上都等價(jià),但是JavaScript不能識(shí)別缤至。

'\u01D1'==='\u004F\u030C' //false

'\u01D1'.length // 1
'\u004F\u030C'.length // 2
'\u01D1'.normalize() === '\u004F\u030C'.normalize() // true

  • NFC潮罪,默認(rèn)參數(shù)康谆,表示“標(biāo)準(zhǔn)等價(jià)合成”(Normalization Form Canonical Composition),返回多個(gè)簡(jiǎn)單字符的合成字符嫉到。所謂“標(biāo)準(zhǔn)等價(jià)”指的是視覺和語義上的等價(jià)沃暗。
  • NFD,表示“標(biāo)準(zhǔn)等價(jià)分解”(Normalization Form Canonical Decomposition)何恶,即在標(biāo)準(zhǔn)等價(jià)的前提下孽锥,返回合成字符分解的多個(gè)簡(jiǎn)單字符。
  • NFKC细层,表示“兼容等價(jià)合成”(Normalization Form Compatibility Composition)惜辑,返回合成字符。所謂“兼容等價(jià)”指的是語義上存在等價(jià)疫赎,但視覺上不等價(jià)盛撑,比如“囍”和“喜喜”。(這只是用來舉例捧搞,normalize方法不能識(shí)別中文抵卫。)
  • NFKD,表示“兼容等價(jià)分解”(Normalization Form Compatibility Decomposition)胎撇,即在兼容等價(jià)的前提下介粘,返回合成字符分解的多個(gè)簡(jiǎn)單字符

正則表達(dá)式u修飾符

let text = '?'
console.log(/^.$/.test(text)); //false
console.log(/^.$/u.test(text)); //true

計(jì)算碼位的數(shù)量

function codePointLength(text){
    let result = text.match(/[\s\S]/gu);
    return result ? result.length : 0;
}
console.log(codePointLength("123a")); //4
console.log(codePointLength("?a")); //2
console.log(codePointLength("?哦")); //2


//emmmmm。運(yùn)行效率蠻低创坞,聽說有更簡(jiǎn)單的受葛,后面演示

字符串中子串的識(shí)別

includes(x,y)檢測(cè)指定字符串返回boolean值题涨,第二參數(shù)是開始位置(0開始數(shù))

let text = "adsdasdasgsgwefsfs";
let subtext = 'asd';
console.log(text.includes(subtext,4)) //true
console.log(text.includes(subtext)) //true
console.log(text.includes('sdadasda')) //false

startsWith(x,y) 和 endsWith(x,y) 檢測(cè)字符串開頭和結(jié)尾的是否與子串相匹配,第二參數(shù)是開始位置(0開始數(shù))

let text = "adsdasdasgsgwefsfs";
let subtext1 = 'ads';
let subtext2 = 'sfs';

console.log(text.startsWith('asd',4)) //true
console.log(text.startsWith(subtext1)) //true
console.log(text.startsWith('sdadasda')) //false


console.log(text.endsWith('gsgwefsfs',18)) //true 以最后一個(gè)字母的位置為準(zhǔn)
console.log(text.endsWith(subtext2)) //true
console.log(text.endsWith('sdadasda')) //false

repeat() 接受一個(gè)number,即將字符重復(fù)的次數(shù)

console.log('x'.repeat(6)); // xxxxxx
console.log('ly'.repeat(3));  //lylyly
console.log('愛'.repeat(2));  //愛愛

正則的語法變更 (蠻頭疼的,正則還是暈乎乎的)

正則表達(dá)式y(tǒng)修飾符

除了u 修飾符闰渔,ES6還為正則表達(dá)式添加了 y 修飾符蒂阱,叫做“粘連”修飾符了嚎。y 修飾符的作用與 g 修飾符類似赘风,也是全局匹配夹囚,后一次匹配都從上一次匹配成功的下一個(gè)位置開始。不同之處在于邀窃,g 修飾符只要剩余位置中存在匹配就可荸哟,而 y 修飾符確保匹配必須從剩余的第一個(gè)位置開始,這也就是“粘連”的含義瞬捕,當(dāng)為匹配到時(shí)鞍历,將會(huì)返回空,lastIndex將會(huì)置為0

var s = 'aaa_aa_a';  
var r1 = /a+/g;  
var r2 = /a+/y;  
  
console.log(r1.exec(s)) //["aaa", index: 0, input: "aaa_aa_a"] console.log(r2.exec(s)) //["aaa", index: 0, input: "aaa_aa_a"]
console.log(r1.lastIndex) //3
console.log(r2.lastIndex) //3


console.log(r1.exec(s)) //["aa", index: 4, input: "aaa_aa_a"]
console.log(r2.exec(s)) //null  
console.log(r1.lastIndex) //6
console.log(r2.lastIndex) //0



console.log(r1.exec(s)) //["a", index: 7, input: "aaa_aa_a"]
console.log(r2.exec(s)) //["aaa", index: 0, input: "aaa_aa_a"] console.log(r1.lastIndex) //8
console.log(r2.lastIndex) //3

檢測(cè)y修飾符是否存在

let pattern = /hello\d/y;

console.log(pattern.sticky) //true  谷歌瀏覽器下

正則表達(dá)式的復(fù)制

es5 如下復(fù)制

var re1 = /ab/i
    re2 = new RegExp(re1);
    console.log(re1.construct === re2.construct) //true

es6新增了可以添加傳修飾符

var re1 = /ab/i
    re2 = new RegExp(re1,'g');
    console.log(re1.toString()) ///ab/i
    console.log(re2.toString()) ///ab/g

flags屬性

source獲取正則表達(dá)式文本 flags獲取其修飾符

let re = /ab/gi;


console.log(re.source); //ab
console.log(re.flags);  //gi

模板字面量

JS 的字符串相對(duì)其他語言來說功能總是有限的肪虎,事實(shí)上劣砍,ES5中一直缺乏許多特性,如多行字符串扇救、字符串格式化刑枝、HTML轉(zhuǎn)義等。ES6通過模板字面量的方式進(jìn)行了填補(bǔ)迅腔,模板字面量試著跳出JS已有的字符串體系装畅,通過一些全新的方法來解決類似的問題

反引號(hào)(``)

const name = 'ly';
let message = `${name},is a man`  //ly,is a man
console.log(message);

//${} 可以寫變量  名叫字符串占位符

console.log(`\`hh\``); //`hh`

//es5 實(shí)現(xiàn)多行文本
var message = " ly  \n \
   love you"
console.log(message);

//es6

var message = ` ly
   love you`
console.log(message); // ly
                      // love you

字符串占位符 ${javascript表達(dá)式}

let count = 15,
    price = .5,
    message = `${count} items cost $${(count*price).toFixed(1)}`;
    console.log(message); //15 items cost $7.5

標(biāo)簽?zāi)0?/h4>

標(biāo)簽?zāi)0迤鋵?shí)不是模板,而是函數(shù)調(diào)用的一種特殊形式沧烈÷有郑“標(biāo)簽”指的是函數(shù),緊跟在后面的模板字符串就是它的參數(shù)

var a = 5;
var b = 10;
tag `Hello ${a+b} world ${a*b}`;
//這個(gè)標(biāo)識(shí)名tag,它是一個(gè)函數(shù)锌雀。整個(gè)表達(dá)式的返回值蚂夕,就是tag函數(shù)處理模板字符串之后的返回值。函數(shù)tag會(huì)依次接收到多個(gè)參數(shù)腋逆。

tag函數(shù)的第一個(gè)參數(shù)是一個(gè)數(shù)組双抽,該數(shù)組的成員時(shí)模板字符串中那些沒有變量替換的部分,也就是說闲礼,變量替換只發(fā)生在數(shù)組的第一個(gè)成員和第二個(gè)成員之間牍汹,以此類推铐维。tag函數(shù)的其他參數(shù)都是模板字符串各個(gè)變量被替換后的值,由于本例中慎菲,模板字符串含有兩個(gè)變量嫁蛇,因此tag會(huì)接收到value1和value2兩個(gè)參數(shù)。
tag函數(shù)所有參數(shù)的實(shí)際值如下:
——第一個(gè)參數(shù):['Hello ',' world ','']
——第二個(gè)參數(shù):15
——第三個(gè)參數(shù):50
也就是說tag函數(shù)實(shí)際上是以下面的形式調(diào)用的
tag(['Hello ',' world ',''],15,50);
我們可以按照需要編寫tag 函數(shù)的代碼露该。

var count = 5;
var price = 10;

function tag(s,v1,v2,v3){
    console.log(s[0]);
    console.log(s[1]);
    console.log(s[2]);
    console.log(s);
    console.log(v1);
    console.log(v2);
    return 'ok'
}
tag`q${count} items cost $${(count*price).toFixed(1)}.`;

//VM173:5 
//VM173:6  items cost $
//VM173:7  .
//VM173:8 5
//VM173:9 50.0
//ok

標(biāo)簽函數(shù)的常用形式

function tag(literals,...substitutions){
    //literals 值得是被${}隔開的字符
    //substitutions睬棚,有幾個(gè)${}就有幾個(gè)這個(gè)
}

利用 literals.length-1 === substitutions.length,拼接字符串

function passthru(literals,...values){
    var output ="";
    for(var index = 0;index<values.length;index++){
        output = literals[index]+values[index];
    }
    output+=literals[index];
    return output;
}

let count = 15,
    price = .5,
    message = passthru`${count} items cost $${(count*price).toFixed(1)}`;
    console.log(message); //15 items cost $7.5

what?這樣做的意義是啥?

emmm,過濾html字符串,還有一些轉(zhuǎn)義字符的過濾

function SaferHTML(templateData){
    var s = templateData[0];
    var i;
    for(i = 1;i<arguments.length;i++){
        var arg = String(arguments[i]);

        //sender里面可能有特殊字符解幼,進(jìn)行轉(zhuǎn)義
        s += arg.replace(/&/g,"&amp;")
                .replace(/</g,"&lt;")
                .replace(/>/g,"&gt;");
        s += templateData[i];
    }
    console.log(i);//2抑党,表示這個(gè)循環(huán)只執(zhí)行了一次,因?yàn)閠emplateData[0]="<p>",arguments這個(gè)數(shù)組只有${sender}這個(gè)元素撵摆,后面一長(zhǎng)串字符都是templateData[2];
    return s;
}
var sender = '<script>alert("abc")</script>';
var message = SaferHTML`<p>${sender} has sent you a message.</p>`;
console.log(message);

在模板字面量中使用原始值

使用內(nèi)建對(duì)象String.raw訪問


let ms1 = `ly\n love you`
let ms2 = String.raw`ly\n love you`

console.log(ms1); //ly
                  //love you

console.log(ms2); // ly\n love you


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末底靠,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子特铝,更是在濱河造成了極大的恐慌暑中,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,123評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鲫剿,死亡現(xiàn)場(chǎng)離奇詭異鳄逾,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)灵莲,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門雕凹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人政冻,你說我怎么就攤上這事枚抵。” “怎么了赠幕?”我有些...
    開封第一講書人閱讀 156,723評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵俄精,是天一觀的道長(zhǎng)询筏。 經(jīng)常有香客問我榕堰,道長(zhǎng),這世上最難降的妖魔是什么嫌套? 我笑而不...
    開封第一講書人閱讀 56,357評(píng)論 1 283
  • 正文 為了忘掉前任逆屡,我火速辦了婚禮,結(jié)果婚禮上踱讨,老公的妹妹穿的比我還像新娘魏蔗。我一直安慰自己,他們只是感情好痹筛,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評(píng)論 5 384
  • 文/花漫 我一把揭開白布莺治。 她就那樣靜靜地躺著廓鞠,像睡著了一般。 火紅的嫁衣襯著肌膚如雪谣旁。 梳的紋絲不亂的頭發(fā)上床佳,一...
    開封第一講書人閱讀 49,760評(píng)論 1 289
  • 那天,我揣著相機(jī)與錄音榄审,去河邊找鬼砌们。 笑死,一個(gè)胖子當(dāng)著我的面吹牛搁进,可吹牛的內(nèi)容都是我干的浪感。 我是一名探鬼主播,決...
    沈念sama閱讀 38,904評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼饼问,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼影兽!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起匆瓜,我...
    開封第一講書人閱讀 37,672評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤赢笨,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后驮吱,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體茧妒,經(jīng)...
    沈念sama閱讀 44,118評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評(píng)論 2 325
  • 正文 我和宋清朗相戀三年左冬,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了桐筏。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,599評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡拇砰,死狀恐怖梅忌,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情除破,我是刑警寧澤牧氮,帶...
    沈念sama閱讀 34,264評(píng)論 4 328
  • 正文 年R本政府宣布,位于F島的核電站瑰枫,受9級(jí)特大地震影響踱葛,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜光坝,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評(píng)論 3 312
  • 文/蒙蒙 一尸诽、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧盯另,春花似錦性含、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)叠萍。三九已至,卻和暖如春绪商,著一層夾襖步出監(jiān)牢的瞬間俭令,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評(píng)論 1 264
  • 我被黑心中介騙來泰國(guó)打工部宿, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留抄腔,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,286評(píng)論 2 360
  • 正文 我出身青樓理张,卻偏偏與公主長(zhǎng)得像赫蛇,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子雾叭,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容