Câu hỏi rất đơn giản: Tôi có một chuỗi
str
, làm cách nào để kiểm tra nếustr
là một biểu tượng cảm xúc duy nhất và không có gì khác? Ngoài ra, tôi không muốn sử dụng một thư viện khác.Trận đấu
"🍎"
,"⛹🏿♂️"
,"3️⃣"
nhưng không phải"🍓a"
,"𝕒"
,"🍌🍀"
Tôi gặp khó khăn khi tìm giải pháp nhưng đây là một số điều tôi đã thử cho đến nay:
Giải pháp đã thử 1 - Chơi xung quanh độ dài và ...
toán tử
Tôi đã học được rằng biểu tượng cảm xúc chiếm nhiều hơn một byte, một số thậm chí chiếm 4 byte hoặc nhiều hơn ... và chúng ta có thể đo lường điều đó thông qua thuộc tính của chuỗi length
:
console.log("🍎".length); // 2
console.log("🛡️".length); // 3
console.log("⛹🏿♂️".length); // 6
Sau đó, tôi phát hiện ra rằng ...
toán tử tính đến điều này và phân tách chính xác biểu tượng cảm xúc trong mảng - sau đó tôi có thể thấy thuộc length
tính của mảng kết quả và phát hiện xem chúng có khác nhau không.
str = "⛹🏿♂️";
if (str.length !== [...str].length) {
// is emoji?
} else {
// is not emoji
}
Nhưng điều này không kiểm tra các ký tự nhiều byte khác, chẳng hạn như 𝕡
độ dài của nó là 2. Ngoài ra, một số biểu tượng cảm xúc vẫn bị tách ra một cách kỳ lạ.
Giải pháp đã thử 2 - Regex, biểu thức chính quy
Tất nhiên regex sẽ là một điều cần xem xét nhưng tôi vẫn chưa tìm được giải pháp khả thi.
Regex của câu trả lời này\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff]
hoạt động hoàn toàn tốt để phát hiện nếu một chuỗi có bất kỳ biểu tượng cảm xúc nào, nhưng áp dụng cho tình huống của tôi, nó tạo ra rất nhiều vấn đề. Dưới đây là các bài kiểm tra của tôi:
Phần A - Không có bắt đầu / kết thúc chuỗi regex ( ^
và $
)
- 2A.1
str.match(regex)
rất không nhất quán, nó phá vỡ một số biểu tượng cảm xúc và một số không thể sử dụng khác. Tôi không thấy cách nào để tìm hiểu xem nó thậm chí có chứa các ký tự không phải biểu tượng cảm xúc hay nếu nó chứa nhiều hơn một biểu tượng cảm xúc:
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)
trả về đúng bất cứ khi nào một biểu tượng cảm xúc được bao gồm trong chuỗi, đó không phải là hành vi tôi đang tìm kiếm:
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
Phần B - Với bắt đầu / kết thúc chuỗi regex ( ^
và $
)
- 2B.1
str.match(regex)
trảnull
về một số biểu tượng cảm xúc nhất định vì một số lý do. Tôi không biết tại sao nhưng tôi cho rằng nó có một số mối quan hệ như tại saostr.match(regex)
sẽ phá vỡ những biểu tượng cảm xúc này trong Phần A:
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)
sẽ trở lạifalse
trên cùng biểu tượng cảm xúc nơi nó sẽ trở lạinull
vàostr.match(regex)
:
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
Phần C - Các biểu thức chính quy khác
- Tôi tìm thấy cái này nhưng nó cho sự không nhất quán tương tự, mặc dù không giống nhau
/(?:[\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
- Ngoài ra, điều này phá vỡ khủng khiếp (thay đổi thử nghiệm thứ hai dựa trên thử nghiệm đầu tiên?)
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
Có cách nào xung quanh tất cả các biểu tượng cảm xúc / unicode / regex này không? Là thư viện / apis là cách duy nhất? Họ làm nó như thế nào?