การใช้JSON.decode
สิ่งนี้มาพร้อมกับข้อเสียที่สำคัญที่คุณต้องระวัง:
- คุณต้องตัดสตริงด้วยเครื่องหมายคำพูดคู่
- ตัวละครหลายตัวไม่ได้รับการสนับสนุนและต้องหลบหนีเอง ยกตัวอย่างเช่นที่ผ่านใด ๆ ต่อไปนี้เพื่อ
JSON.decode
(หลังจากการตัดพวกเขาในราคาคู่) จะเกิดข้อผิดพลาดแม้ว่าเหล่านี้ทั้งหมดที่ถูกต้อง: \\n
, \n
, \\0
,a"a
- ไม่รองรับการหลบหนีเลขฐานสิบหก:
\\x45
- ไม่สนับสนุนลำดับจุดรหัส Unicode:
\\u{045}
มีข้อแม้อื่น ๆ เช่นกัน โดยพื้นฐานแล้วการใช้JSON.decode
เพื่อจุดประสงค์นี้เป็นการแฮ็กและไม่ได้ผลอย่างที่คุณคาดหวังเสมอไป คุณควรใช้JSON
ไลบรารีเพื่อจัดการ JSON ไม่ใช่สำหรับการทำงานของสตริง
ฉันเพิ่งพบปัญหานี้ด้วยตัวเองและต้องการตัวถอดรหัสที่มีประสิทธิภาพดังนั้นฉันจึงลงเอยด้วยการเขียนตัวเอง มันเป็นที่สมบูรณ์และการทดสอบอย่างละเอียดและสามารถใช้ได้ที่นี่: https://github.com/iansan5653/unraw มันเลียนแบบมาตรฐาน JavaScript ได้ใกล้เคียงที่สุด
คำอธิบาย:
ซอร์สมีประมาณ 250 บรรทัดดังนั้นฉันจะไม่รวมทั้งหมดไว้ที่นี่ แต่โดยพื้นฐานแล้วจะใช้ Regex ต่อไปนี้เพื่อค้นหาลำดับการหลีกเลี่ยงทั้งหมดจากนั้นแยกวิเคราะห์โดยใช้parseInt(string, 16)
เพื่อถอดรหัสตัวเลขฐาน 16 จากนั้นจึงString.fromCodePoint(number)
จะได้อักขระที่เกี่ยวข้อง:
/\\(?:(\\)|x([\s\S]{0,2})|u(\{[^}]*\}?)|u([\s\S]{4})\\u([^{][\s\S]{0,3})|u([\s\S]{0,4})|([0-3]?[0-7]{1,2})|([\s\S])|$)/g
แสดงความคิดเห็น (หมายเหตุ: regex นี้ตรงกับลำดับการหลีกเลี่ยงทั้งหมดรวมถึงลำดับที่ไม่ถูกต้องหากสตริงจะส่งข้อผิดพลาดใน JS มันจะแสดงข้อผิดพลาดในไลบรารีของฉัน [เช่น'\x!!'
จะผิดพลาด]):
/
\\ # All escape sequences start with a backslash
(?: # Starts a group of 'or' statements
(\\) # If a second backslash is encountered, stop there (it's an escaped slash)
| # or
x([\s\S]{0,2}) # Match valid hexadecimal sequences
| # or
u(\{[^}]*\}?) # Match valid code point sequences
| # or
u([\s\S]{4})\\u([^{][\s\S]{0,3}) # Match surrogate code points which get parsed together
| # or
u([\s\S]{0,4}) # Match non-surrogate Unicode sequences
| # or
([0-3]?[0-7]{1,2}) # Match deprecated octal sequences
| # or
([\s\S]) # Match anything else ('.' doesn't match newlines)
| # or
$ # Match the end of the string
) # End the group of 'or' statements
/g # Match as many instances as there are
ตัวอย่าง
การใช้ห้องสมุดนั้น:
import unraw from "unraw";
let step1 = unraw('http\\u00253A\\u00252F\\u00252Fexample.com');
let step2 = decodeURIComponent(step1);