วิธีลบตัวแบ่งบรรทัดทั้งหมดออกจากสตริง


440

ฉันมีข้อความเป็น textarea และฉันอ่านมันโดยใช้แอตทริบิวต์. value

ตอนนี้ฉันต้องการที่จะลบ linebreaks ทั้งหมด (ตัวละครที่ผลิตเมื่อคุณกดEnter) จากข้อความของฉันตอนนี้ใช้. แทนที่ด้วยการแสดงออกปกติ แต่ฉันจะระบุ linebreak ใน regex ได้อย่างไร

หากเป็นไปไม่ได้มีวิธีอื่นไหม


คำตอบ:


501

นี่อาจเป็นคำถามที่พบบ่อย อย่างไรก็ตามการขึ้นบรรทัดใหม่ (ดีกว่า: บรรทัดใหม่) สามารถเป็นหนึ่งใน Carriage Return (CR, \rบน Macs รุ่นเก่า), Line Feed (LF \n,, บน Unices รวมถึง Linux) หรือ CR ตามด้วย LF ( \r\n, บน WinDOS) (ตรงกันข้ามกับคำตอบอื่นซึ่งไม่เกี่ยวข้องกับการเข้ารหัสอักขระ)

ดังนั้นRegExpตัวอักษรที่มีประสิทธิภาพที่สุดเพื่อให้ตรงกับรูปแบบทั้งหมดคือ

/\r?\n|\r/

หากคุณต้องการจับคู่บรรทัดใหม่ทั้งหมดในสตริงให้ใช้การจับคู่แบบโกลบอล

/\r?\n|\r/g

ตามลำดับ จากนั้นดำเนินการตามreplaceวิธีที่แนะนำในคำตอบอื่น ๆ (อาจเป็นไปได้ว่าคุณไม่ต้องการลบบรรทัดใหม่ แต่แทนที่ด้วยช่องว่างอื่นตัวอย่างเช่นอักขระเว้นวรรคเพื่อให้คำยังคงเหมือนเดิม)


16
เพื่อความสมบูรณ์ควรสังเกตว่ามีอักขระบรรทัดใหม่ที่แตกต่างกันสี่ตัวใน Unicode: \u000aหรือ\nซึ่งเป็นตัวดึงข้อมูลบรรทัด \u000dหรือ\rซึ่งเป็นรถคืน; \u2028ตัวคั่นบรรทัด และ\u2029ตัวคั่นย่อหน้า ในทางปฏิบัติแม้ว่า regex ที่คุณโพสต์นั้นเพียงพอแล้วในกรณีส่วนใหญ่
งัด Bynens

4
@MathiasBynens ขอบคุณ แต่ U + 2028 และ U + 2029 อย่างชัดเจนไม่ได้เป็นการแบ่งบรรทัดใน HTML (4.01) ซึ่งต้นไม้ DOM และค่าสด textarea จะขึ้นอยู่กับ: w3.org/TR/html4/struct/text.html #whitespace
PointedEars

5
@PointedEars ใช่ แต่เป็นอันดับ HTML ไม่ได้เกิดขึ้นเมื่อตั้ง textarea ของแบบไดนามิกเช่น.value textarea.value = 'a\u2029b'; textarea.value.charAt(1) == '\u2029'; // trueแต่นี่อาจเป็นกรณีที่เป็นขอบ - ตามที่ฉันพูดในกรณีส่วนใหญ่ regex ของคุณเพียงพอ
งัด Bynens

2
@MathiasBynens เนื่องจาก U + 2028 และ U + 2029 ไม่ได้เป็นการขึ้นบรรทัดใหม่ใน HTML (4.01) การกำหนดนั้นจะไม่แสดงสองบรรทัดใน textarea ด้วยการใช้งาน DOM ที่สำคัญและเอ็นจิ้นโครงร่าง ดังนั้นไม่มีใครในใจที่ถูกต้องของพวกเขาจะได้รับมอบหมายในครั้งแรก
แหลม

1
ฉันต้องหนีแบ็กสแลชเพื่อให้การทำงานนี้สำหรับฉันเช่น textIn.replace (/ (\\ r \\ n | \\ n | \\ r) / gm, "") +1 ยัง ขอบคุณ
Crab Bucket

512

วิธีที่คุณจะพบตัวแบ่งบรรทัดแตกต่างกันไประหว่างการเข้ารหัสระบบปฏิบัติการ ของ Windows จะเป็น\r\nแต่เพียงแค่ใช้ลินุกซ์และการใช้แอปเปิ้ล\n\r

ฉันพบสิ่งนี้ในตัวแบ่งบรรทัด JavaScript :

someText = someText.replace(/(\r\n|\n|\r)/gm, "");

ที่ควรลบตัวแบ่งบรรทัดทุกชนิด


18
ทำไมต้องแยก\r\n และ \n และ \rดีกว่าเพียงแค่/[\n\r]/g? แน่นอนว่านี่ช้ากว่าที่ควรจะเป็นเพราะมันแค่ตรวจสอบตัวละครแต่ละตัวกับชุดของตัวเลือกที่เป็นไปได้สองแบบเท่านั้น
Gone Coding

2
เมื่อแยกวิเคราะห์ข้อมูลที่ส่งคืนจาก memcached ใน node.js โดยใช้ / [\ n \ r] / g ขอขอบคุณการเข้ารหัส ตัวเลือกในคำตอบ butchered มัน
Kyle Coots

111

var str = " \n this is a string \n \n \n"

console.log(str);
console.log(str.trim());

String.trim() ลบช่องว่างออกจากจุดเริ่มต้นและจุดสิ้นสุดของสตริง ... รวมถึงการขึ้นบรรทัดใหม่

const myString = "   \n \n\n Hey! \n I'm a string!!!         \n\n";
const trimmedString = myString.trim();

console.log(trimmedString);
// outputs: "Hey! \n I'm a string!!!"

นี่คือตัวอย่างซอ: http://jsfiddle.net/BLs8u/

บันทึก! มันตัดเฉพาะจุดเริ่มต้นและจุดสิ้นสุดของสตริงไม่ใช่ตัวแบ่งบรรทัดหรือช่องว่างในช่วงกลางของสตริง


34
สิ่งนี้จะลบตัวแบ่งบรรทัดออกจากจุดเริ่มต้นและจุดสิ้นสุดของสตริงเท่านั้น OP ถามวิธีลบตัวแบ่งบรรทัดทั้งหมด
Ian Walter

4
ใช่เพียงเพิ่มเป็นตัวเลือก
RobW

1
ทำงานในสิ่งที่ฉันต้องการ - เริ่มต้นและสิ้นสุดของสตริง ขอบคุณ!
Harlin

46

คุณสามารถใช้\nใน regex สำหรับการขึ้นบรรทัดใหม่และ\rสำหรับการขึ้นบรรทัดใหม่

var str2 = str.replace(/\n|\r/g, "");

ระบบปฏิบัติการที่แตกต่างกันใช้ปลายสายที่แตกต่างด้วยการผสมที่แตกต่างกันและ\n \rregex นี้จะแทนที่พวกเขาทั้งหมด


ฉันคิดว่าสิ่งนี้จะแทนที่การเกิดขึ้นครั้งแรกเท่านั้น
Sebas

5
/\n|\r/gถูกเขียนได้อย่างมีประสิทธิภาพมากขึ้นหรือแม้กระทั่ง/[\n\r]/g /[\n\r]+/gหลีกเลี่ยงการสลับเว้นเสียแต่ว่าคุณต้องการ
PointedEars

ไม่แน่ใจว่านี่เป็นปัญหาหรือไม่ มันเป็นสิ่งที่ฉันพูดว่า: ลบทุกอย่างที่ไม่อยู่ในช่วง HEX นั้น ตัวอักษรอะไรที่ขึ้นอยู่กับชุดถ่านแน่นอน แต่โพสต์นี้เกี่ยวกับ ASCII
masi

22

หากคุณต้องการลบอักขระควบคุมทั้งหมดรวมถึง CR และ LF คุณสามารถใช้สิ่งนี้:

myString.replace(/[^\x20-\x7E]/gmi, "")

มันจะลบตัวละครที่ไม่สามารถพิมพ์ได้ทั้งหมด นี้เป็นตัวอักษรทั้งหมดไม่0x20-0x7Eภายในพื้นที่ ASCII แม่มด อย่าลังเลที่จะปรับเปลี่ยนช่วง HEX ตามต้องการ


2
ที่ยังจะเอาตัวละครบางแห่งชาติจากภาษาอื่นที่ไม่ใช่ภาษาอังกฤษ ....
Smentek

21

ทางออกที่ง่ายที่สุดคือ:

let str = '\t\n\r this  \n \t   \r  is \r a   \n test \t  \r \n';
str.replace(/\s+/g, ' ').trim();
console.log(str); // logs: "this is a test"

.replace()ด้วย/\s+/gregexp กำลังเปลี่ยนกลุ่มของอักขระช่องว่างทั้งหมดเป็นช่องว่างเดียวในสตริงทั้งหมดจากนั้นเราจะได้.trim()ผลลัพธ์เพื่อลบช่องว่างสีขาวทั้งหมดก่อนและหลังข้อความ

ถือว่าเป็นอักขระช่องว่าง:
[ \f\n\r\t\v​\u00a0\u1680​\u2000​-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]


ยอดเยี่ยม แต่ฉันทำให้มันทำงานอีกครั้งกำหนดตัวแปร:str = str.replace(/\s+/g, ' ').trim();
Fred K


15

ในการลบตัวอักษรบรรทัดใหม่ให้ใช้สิ่งนี้:

yourString.replace(/\r?\n?/g, '')

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

yourString.trim()

6

คำตอบที่มีให้โดย SharpEars นั้นเป็นทุกสิ่งที่เราต้องการ แต่ต่อไปนี้คำตอบงัด Bynens ของผมไปในการเดินทางวิกิพีเดียและพบนี้: https://en.wikipedia.org/wiki/Newline

ต่อไปนี้เป็นฟังก์ชั่นดร็อปอินที่ใช้ทุกอย่างที่หน้า Wiki ข้างต้นพิจารณาว่า "บรรทัดใหม่" ในเวลาที่ตอบคำถามนี้

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

// replaces all "new line" characters contained in `someString` with the given `replacementString`
const replaceNewLineChars = ((someString, replacementString = ``) => { // defaults to just removing
  const LF = `\u{000a}`; // Line Feed (\n)
  const VT = `\u{000b}`; // Vertical Tab
  const FF = `\u{000c}`; // Form Feed
  const CR = `\u{000d}`; // Carriage Return (\r)
  const CRLF = `${CR}${LF}`; // (\r\n)
  const NEL = `\u{0085}`; // Next Line
  const LS = `\u{2028}`; // Line Separator
  const PS = `\u{2029}`; // Paragraph Separator
  const lineTerminators = [LF, VT, FF, CR, CRLF, NEL, LS, PS]; // all Unicode `lineTerminators`
  let finalString = someString.normalize(`NFD`); // better safe than sorry? Or is it?
  for (let lineTerminator of lineTerminators) {
    if (finalString.includes(lineTerminator)) { // check if the string contains the current `lineTerminator`
      let regex = new RegExp(lineTerminator.normalize(`NFD`), `gu`); // create the `regex` for the current `lineTerminator`
      finalString = finalString.replace(regex, replacementString); // perform the replacement
    };
  };
  return finalString.normalize(`NFC`); // return the `finalString` (without any Unicode `lineTerminators`)
});

3
ครั้งแรก - สำหรับผู้ที่พบสิ่งนี้ไม่ได้ใช้ JS - "RE" สนับสนุนรสชาติมากที่สุด\Rซึ่งก็คือ "ทั้งหมด" linefeeds ประการที่สอง - ทำไมไม่ง่ายsomeString.replace(new RegExp(lineTerminators.join('|')), '');
SamWhan

@ClasG คุณสร้างจุดดี ฉันคิดว่าแนวความคิดของฉันเมื่อฉันเขียนสิ่งนี้คือการทำงานเฉพาะreplace()สิ่งlineTerminatorsที่มีอยู่ในสตริงด้วยเหตุผลด้านประสิทธิภาพเท่านั้น
futz.co

5

Linebreak ใน regex คือ \ n ดังนั้นสคริปต์ของคุณจะเป็น

var test = 'this\nis\na\ntest\nwith\newlines';
console.log(test.replace(/\n/g, ' '));

5

ฉันกำลังเพิ่มคำตอบของฉันมันเป็นเพียงส่วนเสริมด้านบนสำหรับฉันฉันลองใช้ตัวเลือกทั้งหมด / n และมันใช้งานไม่ได้ฉันเห็นข้อความของฉันกำลังส่งจากเซิร์ฟเวอร์ด้วยเครื่องหมายทับสองครั้งดังนั้นฉันจึงใช้สิ่งนี้:

var fixedText = yourString.replace(/(\r\n|\n|\r|\\n)/gm, '');

5

ใช้ฟังก์ชั่นนี้ด้านล่างและทำให้ชีวิตของคุณง่ายขึ้น

วิธีที่ง่ายที่สุดคือการใช้นิพจน์ทั่วไปเพื่อตรวจจับและแทนที่บรรทัดใหม่ในสตริง ในกรณีนี้เราใช้ฟังก์ชั่นแทนที่พร้อมกับสตริงเพื่อแทนที่ด้วยซึ่งในกรณีของเราเป็นสตริงที่ว่างเปล่า

function remove_linebreaks( var message ) {
    return message.replace( /[\r\n]+/gm, "" );
}

ในนิพจน์ด้านบน g และ m มีไว้สำหรับธงส่วนกลางและหลายบรรทัด


2

ลองรหัสต่อไปนี้ มันทำงานได้บนทุกแพลตฟอร์ม

var break_for_winDOS = 'test\r\nwith\r\nline\r\nbreaks';
var break_for_linux = 'test\nwith\nline\nbreaks';
var break_for_older_mac = 'test\rwith\rline\rbreaks';

break_for_winDOS.replace(/(\r?\n|\r)/gm, ' ');
//output
'test with line breaks'

break_for_linux.replace(/(\r?\n|\r)/gm, ' ');
//output
'test with line breaks'

break_for_older_mac.replace(/(\r?\n|\r)/gm, ' ');
// Output
'test with line breaks'

0

บน mac เพียงใช้\nใน regexp เพื่อให้ตรงกับ linebreaks ดังนั้นรหัสจะเป็นstring.replace(/\n/g, '')ps: g ที่ตามมาหมายถึงจับคู่ทั้งหมดแทนที่จะเป็นแค่ตัวแรก

บน Windows, \r\nมันจะเป็น

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