Open toFrankie opened 1 year ago
是这样的,最近在写一个微信公众号的处理脚本,用来替换替换文章中的指定内容。
function getInsertElement(rootElement) { const matchFlag = 'AA' const pList = [...rootElement.querySelectorAll('p')] let matchedElement = pList.find(el => { const text = (el.textContent || el.innerText).replace(/\u00a0/gi, '').trim() return text === matchFlag }) return matchedElement }
上面的方法是脚本的一部分,用于获取文章中指定字符串所在的 DOM 元素,思路是通过 Node.textContent 来匹配的。
Node.textContent
在调试的时候,发现有时候匹配不上,用「肉眼」看是没问题的,但硬是匹配不上。经过一番排查之后,发现了一个有趣的事情,如图:
在编辑器内有字符 AA,然后使用 encodeURIComponent($0.textContent) 的编码结果是 AA%E2%80%8B,所以上面 text === matchFlag 比较结果为 false,自然就匹配不上了。下面将其转换为 Unicode 字符:
AA
encodeURIComponent($0.textContent)
AA%E2%80%8B
text === matchFlag
false
function string2Unicode(str) { return str .split('') .map(value => { const temp = value.charCodeAt(0).toString(16).padStart(4, '0').toUpperCase() if (temp.length > 2) return '\\u' + temp return value }) .join('') } const encodedStr = '%E2%80%8B' const originString = decodeURIComponent(encodedStr) const unicodeStr = string2Unicode(originString) console.log(unicodeStr) // \u200B
转换得出 %E2%80%8B 的 Unicode 编码为 U+200B,然后查询这里发现它是「零宽空格」,是一种不可见的字符。
%E2%80%8B
U+200B
因此,只要使用正则表达式 /\u200b/gi,把所有零宽空格干掉就行了。
/\u200b/gi
function getInsertElement(rootElement) { const matchFlag = 'AA' const pList = [...rootElement.querySelectorAll('p')] let matchedElement = pList.find(el => { const text = (el.textContent || el.innerText) .replace(/\u00a0/gi, '') .replace(/\u200b/gi, '') .trim() return text === matchFlag }) return matchedElement }
零宽空格(zero-width space,ZWSP)是一种不可见、不可打印的 Unicode 字符,用于可能需要换行处。
在 Unicode 中,该字元为 U+200B。在 HTML 中转义字符有:​、​、​。一般情况下,它是不可见的,但一些软件对这些不可见字符做了处理,视觉上可感知。举个例子:
​
​
​
相邻单词之间有一个零宽空格 👇
LoremIpsumDolorSitAmetConsecteturAdipiscingElitSedDoEiusmodTemporIncididuntUtLaboreEtDoloreMagnaAliquaUtEnimAdMinimVeniamQuisNostrudExercitationUllamcoLaborisNisiUtAliquipExEaCommodoConsequatDuisAuteIrureDolorInReprehenderitInVoluptateVelitEsseCillumDoloreEuFugiatNullaPariaturExcepteurSintOccaecatCupidatatNonProidentSuntInCulpaQuiOfficiaDeseruntMollitAnimIdEstLaborum
相邻单词之间无零宽空格 👇
它们在 VS Code 及页面中的展示效果,如图所示:
除此之外,还有零宽连字、零宽不连字也是不可见字符。
零宽连字(zero-width joiner,ZWJ)是一个控制字符,放在某些需要复杂排版语言(如阿拉伯语、印地语)的两个字符之间,使得这两个本不会发生连字的字符产生了连字效果。其 Unicode 编码为 U+200D,HTML 转义字符有:‍、‍。 零宽不连字(zero-width non-joiner,ZWNJ)是一个不打印字符,放在电子文本的两个字符之间,抑制本来会发生的连字,而是以这两个字符原本的字形来绘制。其 Unicode 编码为U+200C,HTML 转义字符有:‌、‌。
零宽连字(zero-width joiner,ZWJ)是一个控制字符,放在某些需要复杂排版语言(如阿拉伯语、印地语)的两个字符之间,使得这两个本不会发生连字的字符产生了连字效果。其 Unicode 编码为 U+200D,HTML 转义字符有:‍、‍。
U+200D
‍
‍
零宽不连字(zero-width non-joiner,ZWNJ)是一个不打印字符,放在电子文本的两个字符之间,抑制本来会发生的连字,而是以这两个字符原本的字形来绘制。其 Unicode 编码为U+200C,HTML 转义字符有:‌、‌。
U+200C
‌
‌
相信你也看过网友「把幸福的一家几口强行分开」的段子,哈哈:
我们利用前面的 string2Unicode() 方法,将其转化为 Unicode 编码,如下:
string2Unicode()
其实它们是由多个字符组合而成的,前面所看到的“空字符串”其实就是 U+200D(零宽连字)。
一篇有趣的文章:Why […‘👩❤️💋👨’] returns [‘👩’, ‘’, ‘❤’, ‘️’, ‘’, ‘💋’, ‘’, ‘👨’] in JavaScript?
零宽字符能做什么?
The end.
背景
是这样的,最近在写一个微信公众号的处理脚本,用来替换替换文章中的指定内容。
上面的方法是脚本的一部分,用于获取文章中指定字符串所在的 DOM 元素,思路是通过
Node.textContent
来匹配的。在调试的时候,发现有时候匹配不上,用「肉眼」看是没问题的,但硬是匹配不上。经过一番排查之后,发现了一个有趣的事情,如图:
在编辑器内有字符
AA
,然后使用encodeURIComponent($0.textContent)
的编码结果是AA%E2%80%8B
,所以上面text === matchFlag
比较结果为false
,自然就匹配不上了。下面将其转换为 Unicode 字符:转换得出
%E2%80%8B
的 Unicode 编码为U+200B
,然后查询这里发现它是「零宽空格」,是一种不可见的字符。因此,只要使用正则表达式
/\u200b/gi
,把所有零宽空格干掉就行了。零宽空格
在 Unicode 中,该字元为
U+200B
。在 HTML 中转义字符有:​
、​
、​
。一般情况下,它是不可见的,但一些软件对这些不可见字符做了处理,视觉上可感知。举个例子:相邻单词之间有一个零宽空格 👇
相邻单词之间无零宽空格 👇
它们在 VS Code 及页面中的展示效果,如图所示:
扩展
除此之外,还有零宽连字、零宽不连字也是不可见字符。
相信你也看过网友「把幸福的一家几口强行分开」的段子,哈哈:
我们利用前面的
string2Unicode()
方法,将其转化为 Unicode 编码,如下:其实它们是由多个字符组合而成的,前面所看到的“空字符串”其实就是
U+200D
(零宽连字)。应用
零宽字符能做什么?
The end.