亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

你真的會(huì)字符串反轉(zhuǎn)、計(jì)算字符串長(zhǎng)度么?

1fe1se / 1342人閱讀

摘要:你真的會(huì)字符串反轉(zhuǎn)計(jì)算字符串長(zhǎng)度么字符串編碼問(wèn)題一個(gè)常見(jiàn)的問(wèn)題如何將字符串反轉(zhuǎn)一個(gè)常見(jiàn)的解答再如,如何得到一個(gè)字符串的長(zhǎng)度答這些答案都不是完全正確,或者說(shuō)并不是對(duì)于所有的字符都是適用的,例如這其中的原因涉及到了的字符串編碼。

你真的會(huì)字符串反轉(zhuǎn)、計(jì)算字符串長(zhǎng)度么? Javascript 字符串編碼 問(wèn)題

一個(gè)常見(jiàn)的問(wèn)題:如何將字符串反轉(zhuǎn)?

一個(gè)常見(jiàn)的解答:

"abcd".split("").reverse().join("") // dcba

再如,如何得到一個(gè)字符串的長(zhǎng)度?

答:

"abcd".length // 4

這些答案都不是完全正確,或者說(shuō)并不是對(duì)于所有的字符都是適用的,例如:

"a?bc".split("").reverse().join("")  cb??a
"a?bc".lenght // 5

"aa?bc".split("").reverse().join("")  cb?aa
"aa?bc".length // 5

這其中的原因涉及到了 Javascript 的字符串編碼。

Unicode 及編碼

Unicode 是一套包含了人類所有的字符、編碼、展示的標(biāo)準(zhǔn)。

Unicode 對(duì)于每一個(gè)字符(character)給了唯一的數(shù)字標(biāo)示,稱為「代碼點(diǎn)」(code point)。也就是說(shuō) Unicode 利用一個(gè)抽象的數(shù)字,即 code point 來(lái)代表字符。Unicode 定義了 1,114,112 個(gè) code point,十六進(jìn)制為 0 到 10FFFF,一般的表示方式為 「U+」開(kāi)頭,后面接十六進(jìn)制表示的 code point,例如:「A」的 code point 為 U+0041。1

在實(shí)際的使用、傳輸 Unicode 中為了減少數(shù)據(jù)大小等需求,一般會(huì)將 code point 編碼(encoding)。一般的 encoding 方式為 「UCS-2」、「UTF-16」、「UTF-8」。

UCS-2:用 16 bit 來(lái)表示 code point?,F(xiàn)在 code point 的范圍已經(jīng)超越了 16 bit 可以表示的了。

UTF-16:對(duì)于可以使用 16 bit 范圍內(nèi)的 code point,就與 UCS-2 相同;否則:

code point 減 0x010000

結(jié)果前 10 bit 加 0xD800,后 10 bit 加 0xDC00

這樣就會(huì)得到兩個(gè) 16 bit 的結(jié)果,范圍分別為:0xD800 - 0xDBFF,和 0xDC00 - 0xDFFF,這兩個(gè)值就代表了相應(yīng)的 code point,一般稱這兩個(gè)值為「surrogate pairs」。

Unicode 標(biāo)準(zhǔn)保證了所有的 code point 都可以用 UTF-16 表示。

UTF-8:

code point 小于 0x7F,則編碼為其本身。

code point 大于 0x7F 小于 0x7FF,編碼為 110+code point 前五位,10+code point 剩下的。

code point 大于 0x7FF 小于 0xFFFF,編碼為 1110+code point 前四位,10+code point 剩下的。

剩下的 code point 編碼為 11110+code point 前三位,10+code point 剩下的六位。

術(shù)語(yǔ)

Unicode 中有很多概念需要厘清,和本文關(guān)系不大,但是對(duì)于更好的理解編碼、或者后續(xù)的更深入的學(xué)習(xí)也是有好處的。

character:

The smallest component of written language that has semantic value; refers to the abstract meaning and/or shape, rather than a specific shape (see also glyph), though in code tables some form of visual representation is essential for the reader’s understanding. 。

grapheme:

A minimally distinctive unit of writing in the context of a particular writing system

例如,英語(yǔ)中的 ,就是兩種不同的grapheme;<ɑ> 就是同一個(gè) grapheme,是字母 a 不同表示。

一個(gè) grapheme 可以用一個(gè)或多個(gè) code point 表示,例如「?」的 code point 為 U+0063 U+0327

String.fromCodePoint(0x0063, 0x0327); // ?

多個(gè) grapheme 也可能只有一個(gè) code point 表示,例如「?」的 code point 為 U+FDFA,但是「?」是有多個(gè) grapheme 組成的。

Sting.fromCodePoint(0xFDFA); // ?

glyph:對(duì)于 grapheme 的可視化的表示。

可以看出,我們一般理解中,「字符」都是為「grapheme」;「字體」、「字號(hào)」等都是「glyph」。

原因

ECMAScript 對(duì)于字符的編碼方式并沒(méi)有嚴(yán)格的約定,但是大部分引擎的實(shí)現(xiàn)都是 UTF-16,但是,Javascript 對(duì)于一個(gè)字符的定義(注意和 Unicode 中 「character」的區(qū)別):

the word “character” will be used to refer to a 16-bit unsigned value used to represent a single 16-bit unit of text 2

不嚴(yán)格的說(shuō)字符串就是一個(gè)個(gè) 16 bit 字符組成的串(從這個(gè)角度來(lái)說(shuō)又和 UCS-2 很相似),也稱為(code units)。

"a?bc"[0] // a
"a?bc"[1] // ?
"a?bc"[2] // ?
"a?bc"[3] // b
"a?bc"[4] // c
    
"aa?bc"[0] // a
"aa?bc"[1] // a
"aa?bc"[2] //  ?
"aa?bc"[3] // b
"aa?bc"[4] // c

「?」的 code point 長(zhǎng)度大于 16 bit 的使用 UTF-16 的「surrogate pairs」即,兩個(gè) 16 bit 來(lái)表示,但同時(shí),內(nèi)部的很多處理都是按照字符(16 bit), 例如:

"a?bc".length === 5

所以就產(chǎn)生了上面字符串反轉(zhuǎn)的問(wèn)題:

String.fromCodePoint(0xD83D, 0xDCA9)  ?

0xD83D 0xDCA9 反轉(zhuǎn)為 0xDCA9 0xD83D 導(dǎo)致錯(cuò)誤的字符串。

「a?」則是由字符「a」和一個(gè) combining marks 「 ?」組合成的一個(gè)字符:

String.fromCodePoint(0x0061, 0x0303)  a?

類似的將其按照 16 bit 反轉(zhuǎn)后就會(huì)有問(wèn)題。

解答

根據(jù) UTF-16 對(duì)于「surrogate pairs」的定義和 「combining marks」的 code point 位置,我們可以自己處理字符串反轉(zhuǎn)的問(wèn)題,

以「surrogate pairs」為例:

const regexSurrogatePair = /([uD800-uDBFF])([uDC00-uDFFF])/g

const reverse = (string) => {
  return string.replace(regexSurrogatePair, ($0, $1, $2) => {
    return $2 + $1 // 先將「surrogate pairs」反轉(zhuǎn)
  }).split("").reverse().join("")
}
    
reverse("a?bc") // cb?a

更全面的庫(kù) esrever。

而對(duì)于「長(zhǎng)度」問(wèn)題:

[..."a?bc"].length // 4

let count = 0

for (let codePoint of "a?bc") {
  count++
}

count // 4

因?yàn)?b>String.prototype[@@iterator]()是遍歷的 code point。

總結(jié)

Javascript 字符串對(duì)外并沒(méi)有暴露 code point ,而是以 16 bit 為單位(UCS-2)提供,導(dǎo)致了 code point 長(zhǎng)度大于 16 bit 的字符(non-BMP)在某些操作上會(huì)有問(wèn)題(反轉(zhuǎn)、取長(zhǎng)度),所以在對(duì)于這種字符就需要特別處理。

  • https://en.wikipedia.org/wiki... ?

  • http://es5.github.io/x6.html#x6 ?

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

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

    相關(guān)文章

    • Python 爬蟲(chóng)面試題 170 道:2019 版

      摘要:下面代碼會(huì)存在什么問(wèn)題,如何改進(jìn)一行代碼輸出之間的所有偶數(shù)。簡(jiǎn)述進(jìn)程之間如何通信多路復(fù)用的作用模型的區(qū)別什么是并發(fā)和并行解釋什么是異步非阻塞的作用面試題說(shuō)說(shuō)你知道的命令如何查看某次提交修改的內(nèi)容答案掃碼下面的二維碼訂閱即可獲取。 引言 最近在刷面試題,所以需要看大量的 Python 相關(guān)的面試題,從大量的題目中總結(jié)了很多的知識(shí),同時(shí)也對(duì)一些題目進(jìn)行拓展了,但是在看了網(wǎng)上的大部分面試題不...

      trigkit4 評(píng)論0 收藏0
    • LeetCode 第 267 場(chǎng)周賽

      摘要:第三組長(zhǎng)度為,奇數(shù),沒(méi)有發(fā)生反轉(zhuǎn)。箭頭指示順序即為單元格填充順序。因此我們采用并查集處理朋友關(guān)系。如果沒(méi)有沖突,再把修改后的副本賦值給原并查集,添加成功否則就認(rèn)為這個(gè)添加無(wú)法進(jìn)行,原并查集對(duì)象不做修改,該請(qǐng)求為。 ...

      Dionysus_go 評(píng)論0 收藏0
    • 老哥真的知道ArrayList#sublist的正確用法

      摘要:我們有這么一個(gè)場(chǎng)景,給你一個(gè)列表,可以動(dòng)態(tài)的新增,但是最終要求列表升序,要求長(zhǎng)度小于,可以怎么做這個(gè)還不簡(jiǎn)單,幾行代碼就可以了測(cè)試驗(yàn)證上面的代碼先不考慮性能的優(yōu)化方面,有沒(méi)有問(wèn)題寫(xiě)了個(gè)簡(jiǎn)單的測(cè)試,我們來(lái)看下會(huì)出現(xiàn)什么情況啟動(dòng)參數(shù)修改 我們有這么一個(gè)場(chǎng)景,給你一個(gè)列表,可以動(dòng)態(tài)的新增,但是最終要求列表升序,要求長(zhǎng)度小于20,可以怎么做? 這個(gè)還不簡(jiǎn)單,幾行代碼就可以了 public Li...

      loonggg 評(píng)論0 收藏0
    • [Leetcode] Shortest Palindrome 最短回文拼接法

      摘要:第二個(gè)是,因?yàn)樵诘趥€(gè)位置,可以有最長(zhǎng)為的相同前后綴,依次類推。匹配時(shí)分為幾種情況字母相同,則和都加,且,因?yàn)楹缶Y匹配的長(zhǎng)度是前綴的長(zhǎng)度加。注意為了方便處理空字符串,我們?cè)诜崔D(zhuǎn)拼接的時(shí)候中間加了,這個(gè)字符要保證不會(huì)出現(xiàn)在字符串中。 Shortest Palindrome Given a string S, you are allowed to convert it to a palin...

      Chiclaim 評(píng)論0 收藏0
    • 60分鐘正則從入門(mén)到深入

      摘要:正則表達(dá)式使用單個(gè)字符串來(lái)描述匹配一系列匹配某個(gè)句法規(guī)則的字符串。接下來(lái),是在手機(jī)正則里面已經(jīng)出現(xiàn)了。序列匹配而則匹配。分組與反向引用分組,又稱為子表達(dá)式。把正則表達(dá)式拆分成小表達(dá)式。 本文轉(zhuǎn)載自網(wǎng)絡(luò)。轉(zhuǎn)載編輯過(guò)程中,可能有遺漏或錯(cuò)誤,請(qǐng)以原文為準(zhǔn)。原文作者:水墨寒湘原文鏈接:https://juejin.im/post/582dfc... 正則表達(dá)式對(duì)于我來(lái)說(shuō)一直像黑暗魔法一樣的存...

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

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

    0條評(píng)論

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