คำถามนั้นง่าย: ฉันมีสตริง
str
ฉันจะตรวจสอบว่าstr
เป็นอีโมจิเดียวและไม่มีอะไรอื่นได้อย่างไร นอกจากนี้ฉันไม่ต้องการใช้ห้องสมุดอื่นMatch
"🍎"
,"⛹🏿♂️"
,"3️⃣"
แต่ไม่"🍓a"
,"𝕒"
,"🍌🍀"
ฉันมีปัญหาในการหาวิธีแก้ไข แต่นี่คือบางสิ่งที่ฉันได้ลองไปแล้ว:
พยายามแก้ปัญหา 1 - เล่นความยาวและ...
ผู้ปฏิบัติงาน
ฉันได้เรียนรู้ว่า emojis ครอบครองมากกว่าหนึ่งไบต์บางคนถึง 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 - Regex นิพจน์ทั่วไป
แน่นอน regex จะเป็นสิ่งที่มองเข้าไป แต่ฉันยังหาวิธีแก้ปัญหาที่ทำงานได้
regex ของคำตอบนี้\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff]
ทำงานได้อย่างสมบูรณ์แบบเพื่อตรวจสอบว่าสตริงมีอิโมจิใด ๆ แต่ใช้กับสถานการณ์ของฉันมันก่อให้เกิดปัญหามากมาย นี่คือการทดสอบของฉัน:
ส่วน A - โดยไม่ต้องเริ่มต้น / สิ้นสุดของสตริง regex ( ^
และ$
)
- 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)
ส่งคืนจริงเมื่อใดก็ตามที่มีอิโมจิรวมอยู่ในสตริงซึ่งไม่ใช่พฤติกรรมที่ฉันกำลังมองหา:
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 - ด้วยการเริ่มต้น / สิ้นสุดของ string regex ( ^
และ$
)
- 2B.1 ให้
str.match(regex)
ผลตอบแทนnull
อีโมจิบางอย่างด้วยเหตุผลบางประการ ฉันไม่มีเงื่อนงำทำไม แต่ฉันคิดว่ามันมีความสัมพันธ์กันว่าทำไมstr.match(regex)
จะทำลายอิโมจิเหล่านี้ในส่วน 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)
จะกลับมาfalse
อยู่กับอีโมจิเดียวกันที่มันจะกลับมาnull
เมื่อวันที่str.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
ส่วน 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
มีวิธีแก้ไขปัญหาทั้งหมดของ emoji / unicode / regex หรือไม่? ไลบรารี / apis เป็นวิธีเดียวหรือไม่ พวกเขาทำมันได้อย่างไร?