มีความแตกต่างระหว่าง / \ s / g และ / \ s + / g หรือไม่?


89

เมื่อเรามีสตริงที่มีอักขระเว้นวรรค:

var str = '  A B  C   D EF ';

และเราต้องการลบช่องว่างออกจากสตริง (เราต้องการสิ่งนี้'ABCDEF':)

ทั้งสองสิ่งนี้:

str.replace(/\s/g, '')

และนี่:

str.replace(/\s+/g, '')

จะส่งคืนผลลัพธ์ที่ถูกต้อง

นี่หมายความว่าสิ่งที่+ไม่จำเป็นในสถานการณ์นี้หรือไม่? มีความแตกต่างระหว่างนิพจน์ทั่วไปทั้งสองในสถานการณ์นี้หรือไม่ (เช่นเดียวกับนิพจน์ทั่วไปจะให้ผลลัพธ์ที่แตกต่างกันในลักษณะใด)


อัปเดต:การเปรียบเทียบประสิทธิภาพ - /\s+/gเร็วกว่า ดูที่นี่: http://jsperf.com/s-vs-s


1
vidas stackoverflow.com/questions/5963182/…ฉันพนันได้เลยว่านี่คือสิ่งที่ทำให้คุณถามคำถามนี้;) (ความคิดเห็นของคุณเกี่ยวกับคำตอบ)
rsplak

2
ฉันนึกภาพออกว่า\s+เร็วกว่าเพราะมันสามารถแทนที่ช่องว่างได้ในขณะที่\sต้องแทนที่แต่ละช่องว่างแยกกัน?
KooiInc

1
@KooiInc: ถูกต้องเพราะตรงกัน / แทนที่น้อยครั้ง
BoltClock

คำตอบ:


219

ใน regex แรกอักขระเว้นวรรคแต่ละตัวจะถูกแทนที่ทีละอักขระด้วยสตริงว่าง

ใน regex ที่สองแต่ละสายที่ต่อเนื่องกัน+ของตัวละครที่พื้นที่จะถูกแทนที่ด้วยสตริงที่ว่างเปล่าเพราะ

อย่างไรก็ตามเช่นเดียวกับการที่ 0 คูณด้วยสิ่งอื่นใดเป็น 0 ดูเหมือนว่าทั้งสองวิธีจะตัดช่องว่างในลักษณะเดียวกัน

หากคุณเปลี่ยนสตริงแทนที่'#'ความแตกต่างจะชัดเจนขึ้นมาก:

var str = '  A B  C   D EF ';
console.log(str.replace(/\s/g, '#'));  // ##A#B##C###D#EF#
console.log(str.replace(/\s+/g, '#')); // #A#B#C#D#EF#

28

\sหมายถึง "ช่องว่างเดียว" และ\s+หมายถึง "ช่องว่างอย่างน้อยหนึ่งช่อง"

แต่เนื่องจากคุณกำลังใช้/gแฟล็ก (แทนที่เหตุการณ์ทั้งหมด) และแทนที่ด้วยสตริงว่างนิพจน์ทั้งสองของคุณจึงมีผลเหมือนกัน


แต่รุ่นที่สองน่าจะเร็วกว่านี้
Tim Pietzcker

หมายความว่าฉันไม่จำเป็นต้องใช้ / g ถ้าฉันใช้ \ s +
Gaurav

1
@Gaurav: ไม่เพราะงั้นมันจะมาแทนที่อันแรก\s+เท่านั้นทำให้ส่วนที่เหลือเหมือนเดิม ตัวอย่างเช่น' foo bar '.replace(/\s+/, '')จะให้คุณ'foo bar ' แก้ไข argh HTML
BoltClock

@Gaurav ฉันไม่คิดอย่างนั้น หากคุณไม่ใช้โมดิgฟายเออร์จะมีการแทนที่เฉพาะครั้งแรกของช่องว่างเท่านั้น
KooiInc

10

ในสถานการณ์การแข่งขันรายการแรกจะส่งคืนการแข่งขันหนึ่งรายการต่อช่องว่างเมื่อรายการที่สองจะส่งคืนการแข่งขันสำหรับแต่ละกลุ่มของช่องว่าง

ผลลัพธ์จะเหมือนกันเนื่องจากคุณกำลังแทนที่ด้วยสตริงว่าง หากคุณแทนที่ด้วย 'x' ผลลัพธ์จะแตกต่างกัน

str.replace(/\s/g, '') จะคืนค่า 'xxAxBxxCxxxDxEF'

ในขณะที่str.replace(/\s+/g, '')จะส่งคืน 'xAxBxCxDxEF'

เพราะ\sจับคู่ช่องว่างแต่ละช่องแทนที่แต่ละช่องด้วย 'x' และ\s+จับคู่กลุ่มของช่องว่างแทนที่ช่องว่างตามลำดับหลายช่องด้วย 'x' ตัวเดียว


3

+หมายถึง "อักขระหนึ่งตัวขึ้นไป" และหากไม่มีเครื่องหมายบวกหมายความว่า "อักขระหนึ่งตัว" ในกรณีของคุณทั้งสองให้ผลลัพธ์เดียวกัน

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