แทนที่อักขระที่ไม่ใช่ตัวเลขอัลฟาเส้นใหม่และช่องว่างหลายช่องด้วยช่องว่างเดียว


136

ฉันกำลังมองหาโซลูชันRegEx ที่เรียบร้อยเพื่อแทนที่

  • อักขระที่ไม่ใช่อัลฟา - ตัวเลขทั้งหมด
  • NewLines ทั้งหมด
  • พื้นที่สีขาวหลายอินสแตนซ์ทั้งหมด

ด้วยช่องว่างเดียว


สำหรับผู้ที่เล่นในบ้าน ( ต่อไปนี้ใช้งานได้ )

text.replace(/[^a-z0-9]/gmi, " ").replace(/\s+/g, " ");

ความคิดของฉันคือRegExอาจมีพลังมากพอที่จะบรรลุสิ่งนี้ในคำสั่งเดียว ส่วนประกอบที่ฉันคิดว่าต้องมีรหัส

  • [^a-z0-9] - เพื่อลบอักขระที่ไม่ใช่อัลฟา - ตัวเลข
  • \s+ - จับคู่คอลเลกชันของช่องว่างใด ๆ
  • \r?\n|\r - จับคู่บรรทัดใหม่ทั้งหมด
  • /gmi - ทั่วโลกหลายบรรทัดไม่คำนึงถึงตัวพิมพ์เล็กและใหญ่

อย่างไรก็ตามฉันไม่สามารถจัดรูปแบบนิพจน์ทั่วไปได้อย่างถูกต้อง ( สิ่งต่อไปนี้ใช้ไม่ได้ )

text.replace(/[^a-z0-9]|\s+|\r?\n|\r/gmi, " ");


อินพุต

234&^%,Me,2 2013 1080p x264 5 1 BluRay
S01(*&asd 05
S1E5
1x05
1x5


ผลลัพธ์ที่ต้องการ

234 Me 2 2013 1080p x264 5 1 BluRay S01 asd 05 S1E5 1x05 1x5

ความพยายามของคุณไม่ได้ผลแค่ไหน? เกิดอะไรขึ้น?
Pointy

คำตอบ:


235

โปรดทราบว่า\W จะทิ้งขีดล่างไว้ เทียบเท่าสั้น ๆ สำหรับ[^a-zA-Z0-9]จะเป็น[\W_]

text.replace(/[\W_]+/g," ");

\Wคือการลบชวเลข \wสำหรับ[A-Za-z0-9_]อักขระคำ (รวมถึงขีดล่าง)

ตัวอย่างที่ regex101.com


ตรวจสอบและทดสอบยังไม่มีประสบการณ์ใน js-regex มากนัก: p Happy you like it
Jonny 5

6
โปรดทราบว่า\Wจะจดจำอักขระที่ไม่ใช่ภาษาละตินเป็นตัวอักษรที่ไม่ใช่คำ
Tyblitz

1
ฉันทำเครื่องหมายคำตอบนี้ว่าถูกต้องหลังจากหลายปีที่ผ่านมาเพราะฉันมองย้อนกลับไปและคำตอบที่ได้รับการยอมรับไม่ได้ยกเว้นขีดล่าง
TheGeneral

143

จอนนี่ 5 เอาชนะฉันไปได้ ฉันจะแนะนำให้ใช้\W+โดยไม่ต้อง\sใน text.replace(/\W+/g, " "). ซึ่งครอบคลุมพื้นที่สีขาวด้วย


ขอบคุณ @ T-CatSan ที่ชี้ให้เห็น! เพิ่มขึ้นและ Saruman คุณมีอิสระที่จะเปลี่ยนคำตอบที่ดีที่สุดให้กับสิ่งใดก็ได้ :-) แต่ควรจะเป็น\W+ไม่ใช่[W+]ก็ดีสวัสดีปีใหม่ทุกคน!
จอนนี่ 5

ขอบคุณ @ Jonny5! ฉันได้ทำการเปลี่ยนแปลงที่คุณแนะนำแล้ว ฉันเคยทดสอบกับวงเล็บมาก่อนและตอนนี้ฉันเห็นว่ามันใช้งานได้โดยไม่มีพวกเขา สวัสดีปีใหม่คุณเช่นกัน
T-CatSan

1
เฮ้ @ T-CatSan มีวิธีเพิ่มข้อยกเว้นไหม? ฉันต้องการรักษาตัวละคร&และ-. เคล็ดลับใด ๆ
Renato Gama

1
ฉันทำการเปลี่ยนแปลงต่อไปนี้ / (\ W +) | (_) / g เพื่อละเว้น _ ด้วย แต่แค่สงสัยว่าทำไมถึงไม่เพิกเฉยในรูปแบบแรกและ regex ของฉันมีประสิทธิภาพหรือไม่
Sridhar Gudimela

14

เนื่องจาก[^a-z0-9]คลาสอักขระมีทั้งหมดที่ไม่ใช่อัลนัมจึงมีอักขระสีขาวด้วย!

 text.replace(/[^a-z0-9]+/gi, " ");

6

ฉันคิดว่าคุณแค่ต้องเพิ่มตัวบ่งชี้ให้กับแต่ละรูปแบบ นอกจากนี้สิ่งที่คืนรถเป็นเรื่องตลกเล็กน้อย:

text.replace(/[^a-z0-9]+|\s+/gmi, " ");

แก้ไข\sสิ่งที่ตรงกัน\rและ\nมากเกินไป


ใช่มีทอม foolery อยู่ในนั้นโดยรวบรวมจากคำตอบอื่น ๆ ในหัวข้อนี้อย่างไรก็ตามขอบคุณมาก!
TheGeneral

2

เห็นโพสต์อื่นที่มีเครื่องหมายกำกับเสียงซึ่งดีมาก

s.replace(/[^a-zA-Z0-9À-ž\s]/g, "")


2

นี่เป็นโพสต์เก่าของฉันคำตอบที่ได้รับการยอมรับนั้นดีสำหรับส่วนใหญ่ อย่างไรก็ตามฉันตัดสินใจที่จะเปรียบเทียบแต่ละโซลูชันและอีกวิธีหนึ่งที่ชัดเจน (เพื่อความสนุกสนาน) ฉันสงสัยว่ามีความแตกต่างระหว่างรูปแบบ regex ในเบราว์เซอร์ต่าง ๆ ที่มีสตริงขนาดต่างกันหรือไม่

โดยพื้นฐานแล้วฉันใช้jsPerfบน

  • การทดสอบใน Chrome 65.0.3325 / Windows 10 0.0.0
  • การทดสอบใน Edge 16.16299.0 / Windows 10 0.0.0

รูปแบบนิพจน์ทั่วไปที่ฉันทดสอบคือ

  • /[\W_]+/g
  • /[^a-z0-9]+/gi
  • /[^a-zA-Z0-9]+/g

ฉันโหลดมันขึ้นมาด้วยความยาวสตริงของอักขระสุ่ม

  • ความยาว 5,000
  • ความยาว 1,000
  • ความยาว 200

ตัวอย่างจาวาสคริปต์ที่ฉันใช้ var newstr = str.replace(/[\W_]+/g," ");

การรันแต่ละครั้งประกอบด้วยตัวอย่าง 50 รายการขึ้นไปในแต่ละ regex และฉันเรียกใช้ 5 ครั้งในแต่ละเบราว์เซอร์

มาแข่งม้าของเรากัน!

ผล

                                Chrome                  Edge
Chars   Pattern                 Ops/Sec     Deviation   Op/Sec      Deviation
------------------------------------------------------------------------
5,000   /[\W_]+/g                19,977.80  1.09         10,820.40  1.32
5,000   /[^a-z0-9]+/gi           19,901.60  1.49         10,902.00  1.20
5,000   /[^a-zA-Z0-9]+/g         19,559.40  1.96         10,916.80  1.13
------------------------------------------------------------------------
1,000   /[\W_]+/g                96,239.00  1.65         52,358.80  1.41
1,000   /[^a-z0-9]+/gi           97,584.40  1.18         52,105.00  1.60
1,000   /[^a-zA-Z0-9]+/g         96,965.80  1.10         51,864.60  1.76
------------------------------------------------------------------------
  200   /[\W_]+/g               480,318.60  1.70        261,030.40  1.80
  200   /[^a-z0-9]+/gi          476,177.80  2.01        261,751.60  1.96
  200   /[^a-zA-Z0-9]+/g        486,423.00  0.80        258,774.20  2.15

เป็นที่ทราบกันดีอยู่แล้วว่า Regex ในเบราว์เซอร์ทั้งสอง (โดยคำนึงถึงค่าเบี่ยงเบน) นั้นแทบจะแยกไม่ออกอย่างไรก็ตามฉันคิดว่าถ้ามันทำงานมากขึ้นหลายครั้งผลลัพธ์จะชัดเจนขึ้นเล็กน้อย (แต่ไม่มาก)

มาตราส่วนตามทฤษฎีสำหรับ 1 อักขระ

                            Chrome                        Edge
Chars   Pattern             Ops/Sec     Scaled            Op/Sec    Scaled
------------------------------------------------------------------------
5,000   /[\W_]+/g            19,977.80  99,889,000       10,820.40  54,102,000
5,000   /[^a-z0-9]+/gi       19,901.60  99,508,000       10,902.00  54,510,000
5,000   /[^a-zA-Z0-9]+/g     19,559.40  97,797,000       10,916.80  54,584,000
------------------------------------------------------------------------

1,000   /[\W_]+/g            96,239.00  96,239,000       52,358.80  52,358,800
1,000   /[^a-z0-9]+/gi       97,584.40  97,584,400       52,105.00  52,105,000
1,000   /[^a-zA-Z0-9]+/g     96,965.80  96,965,800       51,864.60  51,864,600
------------------------------------------------------------------------

  200   /[\W_]+/g           480,318.60  96,063,720      261,030.40  52,206,080
  200   /[^a-z0-9]+/gi      476,177.80  95,235,560      261,751.60  52,350,320
  200   /[^a-zA-Z0-9]+/g    486,423.00  97,284,600      258,774.20  51,754,840

ฉันจะไม่ใช้เวลามากในผลลัพธ์เหล่านี้เพราะนี่ไม่ใช่ความแตกต่างที่สำคัญจริงๆทั้งหมดที่เราบอกได้คือ edge ช้ากว่า: o นอกจากนี้ฉันยังเบื่อสุด ๆ

อย่างไรก็ตามคุณสามารถเรียกใช้เกณฑ์มาตรฐานสำหรับตัวคุณเองได้

Jsperf Benchmark ที่นี่


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