ลบอักขระที่ไม่ใช่ ascii ในสตริง


91
var str="INFO] :谷���新道, ひば���ヶ丘2丁���, ひばりヶ���, 東久留米市 (Higashikurume)";

และฉันต้องการลบอักขระที่ไม่ใช่ ascii ทั้งหมดออกจากสตริง

หมายถึง str มีเฉพาะ "INFO] (Higashikurume)";

คำตอบ:


234

ASCII อยู่ในช่วง 0 ถึง 127 ดังนั้น:

str.replace(/[^\x00-\x7F]/g, "");

8
@AlexanderMills ค้นหาตาราง ascii - คุณจะเห็นว่าเฉพาะอักขระที่มีค่าตั้งแต่ศูนย์ถึง 127 เท่านั้นที่ถูกต้อง (0x7F เท่ากับ 127 ในฐานสิบหก) รหัสนี้จับคู่อักขระทั้งหมดที่ไม่อยู่ในช่วง ascii และลบออก
Zaffy

ขอบคุณสำหรับการแบ่งปัน. คุณช่วยอธิบายว่า \ x7F ทำงานอย่างไร ขอบคุณอีกครั้ง.
eyyo

1
@eyyo IIt แทนอักขระ ascii ตัวสุดท้าย ฉันไม่สามารถให้คำอธิบายทั้งหมดแก่คุณในความคิดเห็นเช่นนี้ได้ เรียกว่าลำดับเลขฐานสิบหกหากคุณค้นหาคุณจะพบข้อมูลมากมายเกี่ยวกับเรื่องนี้
Zaffy

32

นอกจากนี้ยังสามารถทำได้ด้วยการยืนยันการลบในเชิงบวกเช่นนี้:

textContent = textContent.replace(/[\u{0080}-\u{FFFF}]/gu,"");

สิ่งนี้ใช้ Unicode ใน Javascript เมื่อแสดง Unicode สำหรับนิพจน์ทั่วไปอักขระจะถูกระบุด้วยลำดับการหลีกเลี่ยง\u{xxxx}แต่'u'ต้องมีแฟล็กด้วย โปรดสังเกตว่า regex มีแฟล็'gu'

ฉันเรียกสิ่งนี้ว่า "การยืนยันในเชิงบวกในการลบ" ในแง่ที่การยืนยัน "เชิงบวก" เป็นการแสดงออกถึงอักขระที่จะลบในขณะที่การยืนยัน "เชิงลบ" เป็นการแสดงออกถึงตัวอักษรที่จะไม่ลบออก ในหลาย ๆ บริบทการยืนยันเชิงลบดังที่ระบุไว้ในคำตอบก่อนหน้านี้อาจชี้นำผู้อ่านได้มากกว่า วงกลม " ^" \x00-\x7F"" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ไว้ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "ไว้" "" "" "" แล้ว "" "" "" "", " และช่วงที่ระบุว่า" ascii "ทั้งสองจึงรวมกันว่า" ไม่ใช่ ascii "

textContent = textContent.replace(/[^\x00-\x7F]/g,"");

นี่เป็นทางออกที่ดีสำหรับผู้พูดภาษาอังกฤษที่สนใจเฉพาะภาษาอังกฤษและยังเป็นคำตอบที่ดีสำหรับคำถามเดิม แต่ในบริบททั่วไปเราไม่สามารถยอมรับอคติทางวัฒนธรรมของการสมมติว่า "ทั้งหมดที่ไม่ใช่ ascii เป็นสิ่งที่ไม่ดี" สำหรับบริบทที่ใช้ non-ascii แต่ในบางครั้งจำเป็นต้องถอดออกการยืนยัน Unicode ในเชิงบวกจะเหมาะสมกว่า

ข้อบ่งชี้ที่ดีว่าอักขระที่ไม่มีความกว้างเป็นศูนย์ฝังอยู่ในสตริงคือเมื่อคุณสมบัติ "ความยาว" ของสตริงเป็นค่าบวก (ไม่ใช่ศูนย์) แต่ดูเหมือน (เช่นพิมพ์เป็น) สตริงว่าง ตัวอย่างเช่นฉันมีสิ่งนี้ปรากฏในโปรแกรมแก้ไขข้อบกพร่องของ Chrome สำหรับตัวแปรชื่อ "textContent":

> textContent
""
> textContent.length
7

สิ่งนี้กระตุ้นให้ฉันต้องการดูสิ่งที่อยู่ในสตริงนั้น

> encodeURI(textContent)
"%E2%80%8B%E2%80%8B%E2%80%8B%E2%80%8B%E2%80%8B%E2%80%8B%E2%80%8B"

ลำดับของไบต์นี้ดูเหมือนจะอยู่ในตระกูลของอักขระ Unicode บางตัวที่ถูกแทรกโดยตัวประมวลผลคำลงในเอกสารแล้วหาทางเข้าไปในช่องข้อมูล โดยทั่วไปสัญลักษณ์เหล่านี้จะเกิดขึ้นที่ส่วนท้ายของเอกสาร "%E2%80%8B"CK-Editor (CKEditor) อาจแทรกช่องว่างเป็นศูนย์

encodeURI()  UTF-8     Unicode  html     Meaning
-----------  --------  -------  -------  -------------------
"%E2%80%8B"  EC 80 8B  U 200B   ​  zero-width-space
"%E2%80%8E"  EC 80 8E  U 200E   ‎  left-to-right-mark
"%E2%80%8F"  EC 80 8F  U 200F   ‏  right-to-left-mark

การอ้างอิงบางส่วนเกี่ยวกับ:

http://www.fileformat.info/info/unicode/char/200B/index.htm

https://en.wikipedia.org/wiki/Left-to-right_mark

โปรดทราบว่าแม้ว่าการเข้ารหัสของอักขระที่ฝังไว้จะเป็น UTF-8 แต่การเข้ารหัสในนิพจน์ทั่วไปไม่ได้ แม้ว่าอักขระจะฝังอยู่ในสตริงเป็นสามไบต์ (ในกรณีของฉัน) ของ UTF-8 คำแนะนำในนิพจน์ทั่วไปต้องใช้ Unicode สองไบต์ ในความเป็นจริง UTF-8 สามารถมีความยาวได้ถึงสี่ไบต์ มีขนาดกะทัดรัดน้อยกว่า Unicode เนื่องจากใช้บิตสูง (หรือบิต) เพื่อหลีกเลี่ยงการเข้ารหัส ascii มาตรฐาน คำอธิบายที่นี่:

https://en.wikipedia.org/wiki/UTF-8


3
textContent = textContent.replace(/[\u{0080}-\u{FFFF}]/gu,"");ไม่ทำงานใน IE (อย่างน้อย IE 11) ล้มเหลวด้วยข้อผิดพลาด: SCRIPT5021 : ช่วงไม่ถูกต้องในชุดอักขระ
Andrey Sorich

14

คุณสามารถใช้ regex ต่อไปนี้เพื่อแทนที่อักขระที่ไม่ใช่ ASCII

str = str.replace(/[^A-Za-z 0-9 \.,\?""!@#\$%\^&\*\(\)-_=\+;:<>\/\\\|\}\{\[\]`~]*/g, '')

อย่างไรก็ตามโปรดทราบว่าช่องว่างเครื่องหมายทวิภาคและเครื่องหมายจุลภาคเป็น ASCII ที่ถูกต้องทั้งหมดดังนั้นผลลัพธ์จะเป็น

> str
"INFO] :, , ,  (Higashikurume)"

ฉันไม่ค่อยเก่งกับ regex แต่รู้ว่าเมธอด. replace () ใช้สิ่งที่คุณต้องการแทนที่และแทนที่พารามิเตอร์ที่ 2 เช่น. replace ('แทนที่ข้อความนี้', 'ด้วยข้อความนี้') แล้วส่วนไหนของที่บอกว่าทำตรงกันข้ามและปล่อยอักขระ ascii แล้วลบตัวอื่นออก ขอบคุณ.
NicoM

2
อักขระ @NicoM []หมายถึงอักขระใด ๆ แต่ใน[^]ทางกลับกัน - จับคู่อักขระใด ๆ ที่ไม่อยู่ในวงเล็บ
Zaffy

11

คำตอบเหล่านี้ไม่มีคำตอบใดที่จัดการแท็บบรรทัดใหม่การคืนค่าขนส่งได้อย่างถูกต้องและคำตอบบางคำไม่จัดการ ASCII และ Unicode ที่ขยายออกไป สิ่งนี้จะเก็บแท็บ & ขึ้นบรรทัดใหม่ แต่ลบอักขระควบคุมและอะไรก็ได้ออกจากชุด ASCII คลิกปุ่ม "เรียกใช้ข้อมูลโค้ดนี้" เพื่อทดสอบ มีจาวาสคริปต์ใหม่ ๆ เข้ามาในท่อดังนั้นในอนาคต (2020+?) คุณอาจต้องทำ\u{FFFFF}แต่ยังไม่ได้ทำ

console.log("line 1\nline2 \n\ttabbed\nF̸̡̢͓̳̜̪̟̳̠̻̖͐̂̍̅̔̂͋͂͐l̸̢̹̣̤̙͚̱͓̖̹̻̣͇͗͂̃̈͝a̸̢̡̬͕͕̰̖͍̮̪̬̍̏̎̕͘ͅv̸̢̛̠̟̄̿i̵̮͌̑ǫ̶̖͓͎̝͈̰̹̫͚͓̠̜̓̈́̇̆̑͜ͅ".replace(/[\x00-\x08\x0E-\x1F\x7F-\uFFFF]/g, ''))


เป็นนิพจน์ทั่วไปที่ดี แต่ยังลบสำเนียงและอิโมจิ ฉันไม่แน่ใจว่าจะปรับปรุง regex อย่างไรให้ครอบคลุมกรณีเหล่านี้
Julio Vedovatto

สำหรับใครก็ตามที่กำลังมองหาวิธีแก้ปัญหาที่เป็นไปได้ในการลบ Angular window.atob และ DOMSanitizer.bypassSecurity ... อักขระที่ไม่ถูกต้อง (ไม่ว่าจะเป็น% 80, \ uFFFF หรือช่องว่างที่อธิบายไม่ได้) เมื่อแปลงเป็น base64 นี่เป็นโซลูชันที่ใช้งานได้
B. León

10

ในการใช้ ASCII กับสำเนียง:

var str = str.replace(/[^\x00-\xFF]/g, "");

ยอดเยี่ยม! จัดการค่า ascii ที่สูงกว่า 127 ที่คำตอบอื่นทิ้งไป
user3413723

แล้วข้อความแสดงแทนที่มีสำเนียง ... เช่นaltcodeunicode.com/alt-codes-letter-e-with-accentsล่ะ
Stackedup
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.