问题很简单:我有一个字符串
匹配
尝试的解决方法1 - 使用长度和
str
,如何检查str
是否是单个表情符号,且没有其他字符?此外,我不想使用另一个库来实现。匹配
""
,"⛹♂️"
,"3️⃣"
但不能匹配"a"
,""
,""
我在寻找解决方案时遇到了一些问题,这是我迄今为止尝试过的一些方法:
尝试的解决方法1 - 使用长度和...
运算符
我了解到表情符号占用的字节数比较多,有些甚至占用了4个或更多字节,我们可以通过字符串的length
属性进行测量:
console.log("".length); // 2
console.log("️".length); // 3
console.log("⛹♂️".length); // 6
然后我发现...
运算符考虑到了这一点,并正确地将数组中的表情符号分开 - 然后我可以查看结果数组的length
属性并检测它们是否不同。
str = "⛹♂️";
if (str.length !== [...str].length) {
// is emoji?
} else {
// is not emoji
}
但是,这种方法并不能检查其长度为2的其他多字节字符,如。此外,一些表情符号仍然以奇怪的方式分隔。
尝试的解决方法2 - 正则表达式
当然,正则表达式是一个需要考虑的内容,但我还没有找到可行的解决方案。
这个答案的正则表达式 \u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff]
可以完美地检测字符串中是否有任何表情符号,但将其应用于我的情况会产生很多问题。以下是我的测试:
第A部分 - 没有字符串开头/结尾的正则表达式(^
和$
)
- 2A.1
str.match(regex)
非常不一致,它会破坏一些表情符号和其他一些无法使用的符号。我看不出有什么办法可以找出它甚至包含非表情符号字符或者包含多个表情符号:
let regex = /(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])/;
console.log("5️⃣".match(regex)); // [ '⃣', '⃣', index: 2, input: '5️⃣' ]
console.log("".match(regex)); // [ '', '', index: 0, input: '' ]
console.log("️️".match(regex)); // [ '', '', index: 0, input: '️️' ]
console.log("a⛅".match(regex)); // [ '⛅', '⛅', index: 1, input: 'a⛅' ]
- 2A.2
regex.test(str)
会在字符串中包含表情符号时返回true,这不是我想要的行为:
let regex = /(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])/;
console.log(regex.test("5️⃣")); // true - correct
console.log(regex.test("a")); // false - correct
console.log(regex.test("️️")); // true - should be false
console.log(regex.test("hello ⛅!")); // true - should be false
第二部分B - 以字符串开头/结尾的正则表达式(^
和$
)
- 2B.1由于某种原因,在某些表情符号上,
str.match(regex)
会返回null
。我不知道为什么,但我认为这可能与在第一部分A中为什么str.match(regex)
会分解这些表情符号有关:
let regex = /^(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])$/;
console.log("5️⃣".match(regex)); // null
console.log("".match(regex)); // [ '', '', index: 0, input: '' ]
console.log("️".match(regex)); // null
console.log("⛅".match(regex)); // [ '⛅', '⛅', index: 1, input: 'a⛅' ]
console.log("".match(regex)); // null
- 2B.2 对于相同的表情符号,在
regex.test(str)
返回false
的同时,str.match(regex)
将返回null
:
let regex = /^(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])$/;
console.log(regex.test("5️⃣")); // false - should be true
console.log(regex.test("")); // true - correct
console.log(regex.test("️")); // false - should be true
console.log(regex.test("⛅")); // true - correct
console.log(regex.test("")); // false - correct
第 C 部分 - 其他正则表达式
- 我找到了这个,但它给出的不一致性相似,尽管不完全相同
/(?:[\u2700-\u27bf]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff]|[\u0023-\u0039]\ufe0f?\u20e3|\u3299|\u3297|\u303d|\u3030|\u24c2|\ud83c[\udd70-\udd71]|\ud83c[\udd7e-\udd7f]|\ud83c\udd8e|\ud83c[\udd91-\udd9a]|\ud83c[\udde6-\uddff]|[\ud83c[\ude01\uddff]|\ud83c[\ude01-\ude02]|\ud83c\ude1a|\ud83c\ude2f|[\ud83c[\ude32\ude02]|\ud83c\ude1a|\ud83c\ude2f|\ud83c[\ude32-\ude3a]|[\ud83c[\ude50\ude3a]|\ud83c[\ude50-\ude51]|\u203c|\u2049|[\u25aa-\u25ab]|\u25b6|\u25c0|[\u25fb-\u25fe]|\u00a9|\u00ae|\u2122|\u2139|\ud83c\udc04|[\u2600-\u26FF]|\u2b05|\u2b06|\u2b07|\u2b1b|\u2b1c|\u2b50|\u2b55|\u231a|\u231b|\u2328|\u23cf|[\u23e9-\u23f3]|[\u23f8-\u23fa]|\ud83c\udccf|\u2934|\u2935|[\u2190-\u21ff])/g
:
let regex = /^(?:[\u2700-\u27bf]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff]|[\u0023-\u0039]\ufe0f?\u20e3|\u3299|\u3297|\u303d|\u3030|\u24c2|\ud83c[\udd70-\udd71]|\ud83c[\udd7e-\udd7f]|\ud83c\udd8e|\ud83c[\udd91-\udd9a]|\ud83c[\udde6-\uddff]|[\ud83c[\ude01\uddff]|\ud83c[\ude01-\ude02]|\ud83c\ude1a|\ud83c\ude2f|[\ud83c[\ude32\ude02]|\ud83c\ude1a|\ud83c\ude2f|\ud83c[\ude32-\ude3a]|[\ud83c[\ude50\ude3a]|\ud83c[\ude50-\ude51]|\u203c|\u2049|[\u25aa-\u25ab]|\u25b6|\u25c0|[\u25fb-\u25fe]|\u00a9|\u00ae|\u2122|\u2139|\ud83c\udc04|[\u2600-\u26FF]|\u2b05|\u2b06|\u2b07|\u2b1b|\u2b1c|\u2b50|\u2b55|\u231a|\u231b|\u2328|\u23cf|[\u23e9-\u23f3]|[\u23f8-\u23fa]|\ud83c\udccf|\u2934|\u2935|[\u2190-\u21ff])$/g
console.log(regex.test("5️⃣")); // true - correct
console.log(regex.test("")); // false - should be true
console.log(regex.test("️")); // false - should be true
console.log(regex.test("⛅")); // true - correct
console.log(regex.test("")); // false - correct
- 此外,这个地方容易出问题(第二个测试会因为第一个测试而改变吗?)
let regex = /^(?:[\u2700-\u27bf]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff]|[\u0023-\u0039]\ufe0f?\u20e3|\u3299|\u3297|\u303d|\u3030|\u24c2|\ud83c[\udd70-\udd71]|\ud83c[\udd7e-\udd7f]|\ud83c\udd8e|\ud83c[\udd91-\udd9a]|\ud83c[\udde6-\uddff]|[\ud83c[\ude01\uddff]|\ud83c[\ude01-\ude02]|\ud83c\ude1a|\ud83c\ude2f|[\ud83c[\ude32\ude02]|\ud83c\ude1a|\ud83c\ude2f|\ud83c[\ude32-\ude3a]|[\ud83c[\ude50\ude3a]|\ud83c[\ude50-\ude51]|\u203c|\u2049|[\u25aa-\u25ab]|\u25b6|\u25c0|[\u25fb-\u25fe]|\u00a9|\u00ae|\u2122|\u2139|\ud83c\udc04|[\u2600-\u26FF]|\u2b05|\u2b06|\u2b07|\u2b1b|\u2b1c|\u2b50|\u2b55|\u231a|\u231b|\u2328|\u23cf|[\u23e9-\u23f3]|[\u23f8-\u23fa]|\ud83c\udccf|\u2934|\u2935|[\u2190-\u21ff])$/g
console.log(regex.test("⛹♂️")); // false
console.log(regex.test("⛅")); // true
let regex = /^(?:[\u2700-\u27bf]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff]|[\u0023-\u0039]\ufe0f?\u20e3|\u3299|\u3297|\u303d|\u3030|\u24c2|\ud83c[\udd70-\udd71]|\ud83c[\udd7e-\udd7f]|\ud83c\udd8e|\ud83c[\udd91-\udd9a]|\ud83c[\udde6-\uddff]|[\ud83c[\ude01\uddff]|\ud83c[\ude01-\ude02]|\ud83c\ude1a|\ud83c\ude2f|[\ud83c[\ude32\ude02]|\ud83c\ude1a|\ud83c\ude2f|\ud83c[\ude32-\ude3a]|[\ud83c[\ude50\ude3a]|\ud83c[\ude50-\ude51]|\u203c|\u2049|[\u25aa-\u25ab]|\u25b6|\u25c0|[\u25fb-\u25fe]|\u00a9|\u00ae|\u2122|\u2139|\ud83c\udc04|[\u2600-\u26FF]|\u2b05|\u2b06|\u2b07|\u2b1b|\u2b1c|\u2b50|\u2b55|\u231a|\u231b|\u2328|\u23cf|[\u23e9-\u23f3]|[\u23f8-\u23fa]|\ud83c\udccf|\u2934|\u2935|[\u2190-\u21ff])$/g;
console.log(regex.test("⛹")); // true
console.log(regex.test("⛅")); // false
有没有办法解决这些表情符号/Unicode/正则表达式的混乱?是只能使用库/API吗?他们是如何做到的?