你可能不知道的字符串分割技巧
最近看到一個(gè)拆分字符串的新方式,就是使用Intl.Segmenter將emoji字符串分割成字形的方法。
我以前都沒(méi)用過(guò)這個(gè)Intl對(duì)象,現(xiàn)在我們一起來(lái)看看。
假設(shè)你想把用戶(hù)輸入拆分成句子,看起來(lái)是一個(gè)簡(jiǎn)單的 split() 任務(wù)...但這個(gè)問(wèn)題有很多細(xì)微之處。
使用 split() 會(huì)丟失定義的分隔符,并在所有地方包含這些空格。而且因?yàn)樗蕾?lài)于硬編碼的分隔符,所以對(duì)語(yǔ)言不敏感。
我不懂日語(yǔ),但你會(huì)如何嘗試將下面的字符串分割成單詞或句子?
普通的字符串方法在這里是沒(méi)有用的,但是Intl JavaScript API 確能解決這個(gè)問(wèn)題。
Intl.Segmenter 來(lái)救場(chǎng)
Intl.Segmenter 是一個(gè) JavaScript 對(duì)象,用于對(duì)文本進(jìn)行區(qū)域設(shè)置敏感的分段。它可以幫助我們從字符串中提取有意義的項(xiàng)目,如單詞、句子或字形。它的使用方式類(lèi)似于其他的構(gòu)造函數(shù),可以使用 new 關(guān)鍵字來(lái)創(chuàng)建一個(gè) Intl.Segmenter 對(duì)象。
在上面的代碼中,locale 是字符串,表示要使用的區(qū)域設(shè)置。granularity 是字符串,表示分段的粒度。它可以是 "grapheme"(字形)、"word"(單詞)或 "sentence"(句子)之一。
Intl.Segmenter 有一個(gè)很有用的方法叫做 segment(),它可以將文本拆分為有意義的段。
在上面的代碼中,text 是要拆分的文本,segments 是返回的段的迭代器。你可以使用 for-of 循環(huán)來(lái)遍歷段,或者使用 Array.from() 將它們轉(zhuǎn)換為數(shù)組。
Intl.Segmenter 對(duì)象還有其他一些有用的方法,比如 breakType,用于檢索分段的類(lèi)型(例如,句子的末尾是否包含句號(hào))。另一個(gè)有用的方法是 breakType,用于檢索分段的類(lèi)型。
例如:
Intl.Segmenter 還有一個(gè)很有用的靜態(tài)方法叫做 supportedLocalesOf(),它可以幫助你確定瀏覽器是否支持特定的區(qū)域設(shè)置。
在上面的代碼中,supported 數(shù)組包含瀏覽器支持的區(qū)域設(shè)置。
如果你想要對(duì)文本進(jìn)行更細(xì)粒度的分段,你可以使用 Intl.ListFormat 對(duì)象。它可以幫助你將文本拆分為有意義的列表項(xiàng)。
使用方式類(lèi)似于 Intl.Segmenter,你可以使用 new 關(guān)鍵字創(chuàng)建一個(gè) Intl.ListFormat 對(duì)象。
在上面的代碼中,locale 是字符串,表示要使用的區(qū)域設(shè)置。style 和 type 是對(duì)象的屬性,用于指定列表格式。style 可以是 "long" 或 "short",type 可以是 "conjunction"(并列)或 "disjunction"(或)。
Intl.ListFormat 有一個(gè)很有用的方法叫做 format(),它可以將數(shù)組轉(zhuǎn)換為有意義的列表。
在上面的代碼中,formatted 是轉(zhuǎn)換后的列表字符串。
Word 的顆粒度帶有一個(gè)額外的isWordLike屬性
如果把一個(gè)字符串分割成單詞,所有的片段都包括空格和換行符。使用isWordLike屬性將它們過(guò)濾掉。
上面通過(guò)isWordLike進(jìn)行過(guò)濾會(huì)刪除標(biāo)點(diǎn)符號(hào),如.、-、或?。
使用 Intl.Segmenter 來(lái)分割 emojis
如果你想把一個(gè)字符串分割成可視化的emojis,Intl.Segmenter也是一個(gè)很好的幫助。
請(qǐng)注意,字形也包括空格和 "正常 "字符。
編輯中可能存在的bug沒(méi)法實(shí)時(shí)知道,事后為了解決這些bug,花了大量的時(shí)間進(jìn)行l(wèi)og 調(diào)試,這邊順便給大家推薦一個(gè)好用的BUG監(jiān)控工具 Fundebug。
參考
- ??https://www.stefanjudis.com/today-i-learned/how-to-split-javascript-strings-with-intl-segmenter/??
- ??https://2ality.com/2022/11/regexp-v-flag.html??
原文:https://www.stefanjudis.com/today-i-learned/how-to-split-javascript-strings-with-intl-segmenter/
最后
本文譯自:https://marmelab.com/blog/2022/09/20/react-i-love-you.html