成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

JavaScript拆分字符串時(shí)產(chǎn)生空字符的原因

itvincent / 602人閱讀

摘要:?jiǎn)栴}描述使用的方法拆分字符串時(shí)出現(xiàn)一些空字符串,尤其是當(dāng)使用正則表達(dá)式作為分隔符的時(shí)候。如果分隔符是字符串,進(jìn)行匹配判斷,失敗返回,成功返回類型的結(jié)果。如,另一種情況是字符串開頭的一個(gè)或幾個(gè)字符匹配分隔符。

問(wèn)題描述

使用JavaScript的split方法拆分字符串時(shí)出現(xiàn)一些空字符串"",尤其是當(dāng)使用正則表達(dá)式作為分隔符的時(shí)候。

相關(guān)問(wèn)題
  

javascript正則表達(dá)式對(duì)字符串分組時(shí)產(chǎn)生空字符串組?

在上面這個(gè)問(wèn)題中,題主使用正則表達(dá)式對(duì)字符串進(jìn)行分割時(shí)產(chǎn)生了多個(gè)空字符串"",代碼如下:

"張sdf四上法asdf翁芬aa33網(wǎng)s".split(/([u4e00-u9fa5]{1})/gi);
//輸出["", "張", "sdf", "四", "", "上", "", "法", "asdf", "翁", "", "芬", "aa33", "網(wǎng)", "s"]

那么,產(chǎn)生這些空字符串的原因是什么?

問(wèn)題分析

在Google上搜索了一番,發(fā)現(xiàn)相關(guān)的結(jié)果并不多,即便有,詳細(xì)解釋的也不多,大概的說(shuō)了一下,然后就給出了一個(gè)ECMAScript規(guī)范的鏈接??磥?lái)要想知道真正的原因,就只能硬著頭皮看規(guī)范了。

相關(guān)標(biāo)準(zhǔn)

那么,接下來(lái),按照國(guó)際慣例,先上ECMAScript的標(biāo)準(zhǔn)鎮(zhèn)樓。

  

String.prototype.split (separator, limit)

這個(gè)章節(jié)詳細(xì)介紹了split方法的執(zhí)行步驟,如果感興趣的話可以一步一步的認(rèn)真看完,我在這里只把和產(chǎn)生空字符串相關(guān)的步驟拿出來(lái)解釋一下,不當(dāng)之處,歡迎大家提出。

相關(guān)步驟

摘取部分步驟:

整個(gè)過(guò)程中最主要的步驟是第13步這個(gè)循環(huán),而這個(gè)循環(huán)主要做的事情如下:

定義p, q的值,每一次循環(huán)開始的時(shí)候pq的值是相同的(該步驟在循環(huán)之外);

調(diào)用SplitMatch(S, q, R)這個(gè)方法對(duì)字符串進(jìn)行拆分;

根據(jù)返回結(jié)果的不同,執(zhí)行不同的分支,主要分支為分支

分支又分成了8個(gè)小步用來(lái)將返回的結(jié)果填充到事先定義好的數(shù)組A

在這個(gè)8小步中,步驟1的作用是返回原始字符串的一個(gè)子串,開始位置是p(包含在內(nèi)),結(jié)束位置是q(不包含在內(nèi)),注意:在這一步中會(huì)產(chǎn)生空字符串,我將其標(biāo)記為截取字符串,方便下文引用。

將上一步的子串添加到數(shù)組A

接下來(lái)的幾步是更新相關(guān)的變量,繼續(xù)下一次循環(huán)。(步驟7的作用是將正則表達(dá)式中的捕獲分組保存到數(shù)組A中,和產(chǎn)生空字符串無(wú)關(guān))

SplitMatch(S, q, R)

接下來(lái),我們需要了解一下SplitMatch(S, q, R)這個(gè)方法做了些什么事。這個(gè)方法在split規(guī)范中的下方有提及。它主要做的事是,根據(jù)分隔符(separator)的類型進(jìn)行相應(yīng)的操作:

如果分隔符是RegExp類型的,調(diào)用RegExp的內(nèi)部方法[[Match]]來(lái)對(duì)字符串進(jìn)行匹配,如果匹配失敗,返回failure,否則,返回一個(gè)MatchResult類型的結(jié)果。

如果分隔符是字符串,進(jìn)行匹配判斷,失敗返回failure,成功返回MatchResult類型的結(jié)果。

MatchResult

上面的步驟中又引出了一個(gè)MatchResult類型的變量。通過(guò)查文檔發(fā)現(xiàn),該類型的變量有兩個(gè)屬性endIndexcaptures,endIndex的值是字符串匹配的位置加上1,captures可以理解為一個(gè)數(shù)組,當(dāng)分隔符為正則表達(dá)式時(shí),它里面的元素是分組捕獲的值;當(dāng)分隔符為字符串時(shí),它為一個(gè)空數(shù)組。

接下來(lái)

我們從上面的步驟可以看出,分割的字符串是在截取字符串這一步驟中產(chǎn)生的(正則表達(dá)式的分組捕獲除外)。它的作用是截取指定開始(包含在內(nèi))和結(jié)束位置(不包含在內(nèi))之間的字符串,那它什么時(shí)候會(huì)返回""呢?有一種特殊情況是開始位置和結(jié)束位置的值相等,這只是猜想而已,因?yàn)樵撘?guī)范沒有給出截取字符串的規(guī)范步驟。

都走到這里了,為什么不再往前走一步呢?

于是,我試著搜索了一些V8的源碼,看看能不能找到具體的實(shí)現(xiàn)方法。確實(shí)找到了相關(guān)的代碼,源碼鏈接

這里摘取其中一部分:

function StringSplitJS(separator, limit) {
  ...
  ...
  //分隔符是字符串的情況
  if (!IS_REGEXP(separator)) {
    var separator_string = TO_STRING_INLINE(separator);

    if (limit === 0) return [];

    // ECMA-262 says that if separator is undefined, the result should
    // be an array of size 1 containing the entire string.
    if (IS_UNDEFINED(separator)) return [subject];

    var separator_length = separator_string.length;

    //分隔符是空字符串,直接返回了字符數(shù)組
    if (separator_length === 0) return %StringToArray(subject, limit);

    var result = %StringSplit(subject, separator_string, limit);

    return result;
  }

  if (limit === 0) return [];

  // 分隔符是正則表達(dá)式的情況,調(diào)用StringSplitOnRegExp
  return StringSplitOnRegExp(subject, separator, limit, length);
}

//此處省略若干代碼

我在代碼中發(fā)現(xiàn),在填充數(shù)組的時(shí)候會(huì)調(diào)用%_SubString這個(gè)方法來(lái)截取字符串,可惜的是我沒有找到他的相關(guān)定義,如果有找到的同學(xué)歡迎告知。但是,我發(fā)現(xiàn)JavaScript中substring這個(gè)方法所對(duì)應(yīng)的StringSubstring這個(gè)方法會(huì)調(diào)用%_SubString這個(gè)方法,并將其結(jié)果返回。那么如果"abc".substring(1,1)返回"",則表明%_SubString這個(gè)方法在開始位置和結(jié)束位置相同的時(shí)候會(huì)返回"",結(jié)果大家一試便知。

那么,什么時(shí)候會(huì)出現(xiàn)開始位置等于結(jié)束位置(即q === p)的情況呢?我按照上面的步驟一步一步的進(jìn)行分析,最終發(fā)現(xiàn):

當(dāng)原始字符串S匹配過(guò)一次分隔符之后,緊接著,字符串S的下一個(gè)位置還匹配分隔符。如:"abbbc".split("b"),"abbbc".split(/(b){1}/)

另一種情況是字符串開頭的一個(gè)或幾個(gè)字符匹配分隔符。如:"abc".split("a"),"abc".split(/ab/)

還有一種情況是字符串結(jié)尾的一個(gè)或幾個(gè)字符串匹配分隔符,與之相關(guān)的步驟是第14步。
如:"abc".split("c")"abc".split(/bc/)

此外,當(dāng)使用正則表達(dá)式作為分隔符的時(shí)候,返回的結(jié)果中還有可能出現(xiàn)undefined。
如:"abc".split(/(d)*/)

回過(guò)頭來(lái)再看看開頭的那個(gè)例子,是不是滿足上面幾種情況?

題外話

這是我第一次這么仔細(xì)的看ECMAScript的標(biāo)準(zhǔn)規(guī)范,看的過(guò)程確實(shí)很痛苦,但明白之后就感覺很痛快了。也感謝題主提出的這個(gè)問(wèn)題,以及追問(wèn)。
順便提一句,正則表達(dá)式作為分隔符時(shí),global修飾符g是會(huì)被忽略的,這也算是一次額外的收獲。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/85303.html

相關(guān)文章

  • XSS跨站腳本攻擊

    摘要:三攻擊分類反射型又稱為非持久性跨站點(diǎn)腳本攻擊,它是最常見的類型的。存儲(chǔ)型又稱為持久型跨站點(diǎn)腳本,它一般發(fā)生在攻擊向量一般指攻擊代碼存儲(chǔ)在網(wǎng)站數(shù)據(jù)庫(kù),當(dāng)一個(gè)頁(yè)面被用戶打開的時(shí)候執(zhí)行。例如,當(dāng)錯(cuò)誤,就會(huì)執(zhí)行事件利用跨站。 一、簡(jiǎn)介 XSS(cross site script)是指惡意攻擊者利用網(wǎng)站沒有對(duì)用戶提交數(shù)據(jù)進(jìn)行轉(zhuǎn)義處理或者過(guò)濾不足的缺點(diǎn),進(jìn)而添加一些代碼,嵌入到web頁(yè)面中去。使別...

    BingqiChen 評(píng)論0 收藏0
  • XSS跨站腳本攻擊

    摘要:三攻擊分類反射型又稱為非持久性跨站點(diǎn)腳本攻擊,它是最常見的類型的。存儲(chǔ)型又稱為持久型跨站點(diǎn)腳本,它一般發(fā)生在攻擊向量一般指攻擊代碼存儲(chǔ)在網(wǎng)站數(shù)據(jù)庫(kù),當(dāng)一個(gè)頁(yè)面被用戶打開的時(shí)候執(zhí)行。例如,當(dāng)錯(cuò)誤,就會(huì)執(zhí)行事件利用跨站。 一、簡(jiǎn)介 XSS(cross site script)是指惡意攻擊者利用網(wǎng)站沒有對(duì)用戶提交數(shù)據(jù)進(jìn)行轉(zhuǎn)義處理或者過(guò)濾不足的缺點(diǎn),進(jìn)而添加一些代碼,嵌入到web頁(yè)面中去。使別...

    zsirfs 評(píng)論0 收藏0
  • 不要阻塞事件循環(huán)(或工作池)

    摘要:接下來(lái)的部分將討論如何確保事件循環(huán)和工作池的公平調(diào)度。不要阻塞事件循環(huán)事件循環(huán)通知每個(gè)新客戶端連接并協(xié)調(diào)對(duì)客戶端的響應(yīng)。 你應(yīng)該閱讀本指南嗎? 如果您編寫比命令行腳本更復(fù)雜的程序,那么閱讀本文可以幫助您編寫性能更高,更安全的應(yīng)用程序。 在編寫本文檔時(shí),主要是基于Node服務(wù)器。但里面的原則也適用于其它復(fù)雜的Node應(yīng)用程序。在沒有特別說(shuō)明操作系統(tǒng)的情況下,默認(rèn)為L(zhǎng)inux。 TL; D...

    widuu 評(píng)論0 收藏0
  • CSS和網(wǎng)絡(luò)性能

    摘要:對(duì)于性能來(lái)說(shuō)真的非常糟糕。的推出使網(wǎng)頁(yè)性能提高了大約,所有這些都不需要開發(fā)人員參與。這意味著和中的存在錯(cuò)誤。將放在中這個(gè)最終策略是一個(gè)相對(duì)較新的策略,對(duì)感知性能和漸進(jìn)式渲染有很大好處。 CSS對(duì)于呈現(xiàn)頁(yè)面至關(guān)重要 - 在找到,下載和解析所有CSS之前,瀏覽器不會(huì)開始呈現(xiàn) - 因此我們必須盡可能快地將其加載到用戶的設(shè)備上。 關(guān)鍵路徑上的任何延遲都會(huì)影響我們的開始渲染并讓用戶看到空白屏幕。...

    chanthuang 評(píng)論0 收藏0
  • CSS和網(wǎng)絡(luò)性能

    摘要:對(duì)于性能來(lái)說(shuō)真的非常糟糕。的推出使網(wǎng)頁(yè)性能提高了大約,所有這些都不需要開發(fā)人員參與。這意味著和中的存在錯(cuò)誤。將放在中這個(gè)最終策略是一個(gè)相對(duì)較新的策略,對(duì)感知性能和漸進(jìn)式渲染有很大好處。 CSS對(duì)于呈現(xiàn)頁(yè)面至關(guān)重要 - 在找到,下載和解析所有CSS之前,瀏覽器不會(huì)開始呈現(xiàn) - 因此我們必須盡可能快地將其加載到用戶的設(shè)備上。 關(guān)鍵路徑上的任何延遲都會(huì)影響我們的開始渲染并讓用戶看到空白屏幕。...

    techstay 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<