เป็นอย่างไร\r
และ\n
แตกต่างกันอย่างไร ฉันคิดว่ามันเกี่ยวกับ Unix กับ Windows กับ Mac แต่ฉันไม่แน่ใจว่ามันแตกต่างกันอย่างไรและจะค้นหา / จับคู่ใน regexes ได้อย่างไร
เป็นอย่างไร\r
และ\n
แตกต่างกันอย่างไร ฉันคิดว่ามันเกี่ยวกับ Unix กับ Windows กับ Mac แต่ฉันไม่แน่ใจว่ามันแตกต่างกันอย่างไรและจะค้นหา / จับคู่ใน regexes ได้อย่างไร
คำตอบ:
พวกเขาเป็นตัวละครที่แตกต่างกัน \r
คือการขึ้น\n
บรรทัดใหม่และเป็นตัวดึงข้อมูลบรรทัด
บนเครื่องพิมพ์ "เก่า" \r
ส่งหัวพิมพ์กลับไปที่จุดเริ่มต้นของบรรทัดและ\n
ขั้นสูงกระดาษหนึ่งบรรทัด ทั้งคู่จึงจำเป็นต้องเริ่มพิมพ์ในบรรทัดถัดไป
เห็นได้ชัดว่าตอนนี้ไม่เกี่ยวข้องเลยแม้ว่าจะขึ้นอยู่กับคอนโซลคุณอาจยังสามารถใช้\r
เพื่อย้ายไปที่จุดเริ่มต้นของบรรทัดและเขียนทับข้อความที่มีอยู่
ที่สำคัญกว่ายูนิกซ์มีแนวโน้มที่จะใช้\n
เป็นตัวแยกบรรทัด หน้าต่างมีแนวโน้มที่จะใช้\r\n
เป็นตัวคั่นบรรทัดและแม็ค (ถึง OS 9) ที่ใช้กับการใช้\r
เป็นตัวคั่นบรรทัด (Mac OS X คือ Unix-y ดังนั้นควรใช้\n
แทน แต่อาจมีสถานการณ์ความเข้ากันได้บางอย่างที่\r
ใช้แทน)
สำหรับข้อมูลเพิ่มเติมโปรดดูที่บทความวิกิพีเดียขึ้นบรรทัดใหม่
แก้ไข: นี่คือภาษาที่ละเอียดอ่อน ใน C # และ Java ตัวอย่างเช่น\n
มักจะหมายถึง Unicode U + 000A ซึ่งถูกกำหนดให้เป็นอาหารเส้น ใน C และ C ++ น้ำค่อนข้าง muddier เป็นความหมายเฉพาะแพลตฟอร์ม ดูความคิดเห็นเพื่อดูรายละเอียด
\n
มีการรับประกันว่าจะขึ้นบรรทัดใหม่ (มาตรา 2.4.4.4) แน่นอนว่ามันจะดีถ้า OP ได้ระบุแพลตฟอร์ม ... นอกจากนี้ฉันคิดว่ารายละเอียดในระดับนี้จะสับสนมากกว่าประโยชน์สำหรับใครบางคนที่ถามถึงความแตกต่าง
ใน C และ C ++ \n
เป็นแนวคิด\r
คืออักขระและ\r\n
(เกือบทุกครั้ง) บั๊กความสามารถในการพกพา
คิดว่าโทรพิมพ์เก่า หัวพิมพ์อยู่ในตำแหน่งที่เหมาะสมในบางบรรทัดและในบางคอลัมน์ เมื่อคุณส่งอักขระที่พิมพ์ได้ไปยังโทรพิมพ์พิมพ์อักขระที่ตำแหน่งปัจจุบันและย้ายหัวไปยังคอลัมน์ถัดไป (นี่คือแนวคิดเหมือนกับเครื่องพิมพ์ดีดยกเว้นเครื่องพิมพ์ดีดมักจะย้ายกระดาษที่เกี่ยวกับหัวพิมพ์)
เมื่อคุณต้องการที่จะจบบรรทัดปัจจุบันและเริ่มต้นในบรรทัดถัดไปคุณต้องทำสองขั้นตอนแยกจากกัน:
ASCII เข้ารหัสการกระทำเหล่านี้เป็นอักขระควบคุมสองตัวที่แตกต่างกัน:
\x0D
(CR) เลื่อนหัวพิมพ์กลับไปที่จุดเริ่มต้นของบรรทัด (Unicode เข้ารหัสสิ่งนี้เป็นU+000D CARRIAGE RETURN
.)\x0A
(LF) เลื่อนหัวพิมพ์ลงไปที่บรรทัดถัดไป (Unicode เข้ารหัสสิ่งนี้เป็นU+000A LINE FEED
.)ในยุคของโทรศัพท์และเครื่องพิมพ์เทคโนโลยียุคแรกผู้คนใช้ประโยชน์จากความจริงที่ว่าสิ่งเหล่านี้เป็นการดำเนินการแยกกันสองอย่าง โดยการส่ง CR โดยไม่ทำตามโดย LF คุณสามารถพิมพ์บนบรรทัดที่คุณพิมพ์ไปแล้ว เอฟเฟกต์ที่อนุญาตเช่นเน้นเสียง, ตัวหนา, และขีดเส้นใต้ ระบบบางระบบพิมพ์ทับหลาย ๆ ครั้งเพื่อป้องกันไม่ให้รหัสผ่านปรากฏในสำเนาถาวร สำหรับเทอร์มินัล CRT แบบอนุกรม CR เป็นวิธีหนึ่งในการควบคุมตำแหน่งเคอร์เซอร์เพื่ออัปเดตข้อความบนหน้าจอ
แต่ส่วนใหญ่แล้วคุณแค่อยากไปที่บรรทัดถัดไป แทนที่จะต้องการคู่ของอักขระควบคุมระบบบางระบบอนุญาตเพียงหนึ่งหรืออย่างอื่น ตัวอย่างเช่น:
U+0085 NEXT LINE
แต่ค่า EBCDIC 0x15
ที่เกิดขึ้นจริงทำไมระบบที่แตกต่างกันถึงเลือกวิธีที่ต่างกัน เพียงเพราะไม่มีมาตรฐานสากล แป้นพิมพ์ของคุณอาจระบุว่า "Enter" แป้นพิมพ์ที่เก่ากว่าเคยพูดว่า "Return" ซึ่งย่อมาจาก Carriage Return ในความเป็นจริงบนเทอร์มินัลอนุกรมกด Return จริง ๆ ส่งอักขระ CR หากคุณกำลังเขียนโปรแกรมแก้ไขข้อความมันจะเป็นการดึงดูดให้ใช้ตัวละครนั้นเมื่อเข้ามาจากเครื่องเทอร์มินัล บางทีนั่นอาจเป็นเหตุผลที่ Mac รุ่นเก่าใช้เพียง CR
ตอนนี้เรามีมาตรฐานแล้วมีวิธีมากขึ้นในการเป็นตัวแบ่งบรรทัด แม้ว่า Unicode จะหายากมาก แต่ Unicode ก็มีตัวละครใหม่ ๆ เช่น:
U+2028 LINE SEPARATOR
U+2029 PARAGRAPH SEPARATOR
ก่อนที่ Unicode จะเข้ามาโปรแกรมเมอร์ต้องการวิธีง่าย ๆ ในการแสดงรหัสควบคุมที่มีประโยชน์ที่สุดโดยไม่ต้องกังวลเกี่ยวกับชุดอักขระพื้นฐาน C มีหลายลำดับ escape สำหรับการแทนรหัสควบคุม:
\a
(สำหรับการแจ้งเตือน) ซึ่งส่งเสียงสัญญาณโทรพิมพ์หรือส่งเสียงบี๊บ\f
(สำหรับฟีดฟอร์ม) ซึ่งย้ายไปที่จุดเริ่มต้นของหน้าถัดไป\t
(สำหรับแท็บ) ซึ่งย้ายหัวพิมพ์ไปยังตำแหน่งแท็บแนวนอนถัดไป(รายการนี้ไม่สมบูรณ์โดยเจตนา)
การทำแผนที่นี้เกิดขึ้นในเวลารวบรวม - คอมไพเลอร์มองเห็น\a
และกำหนดค่าวิเศษที่จะใช้เพื่อส่งสัญญาณเตือน
โปรดสังเกตว่าตัวช่วยจำส่วนใหญ่เหล่านี้มีความสัมพันธ์โดยตรงกับรหัสควบคุม ASCII ยกตัวอย่างเช่นจะแมปไป\a
0x07 BEL
คอมไพเลอร์สามารถเขียนสำหรับระบบที่ใช้อย่างอื่นที่ไม่ใช่ ASCII สำหรับชุดอักขระโฮสต์ (เช่น EBCDIC) รหัสควบคุมส่วนใหญ่ที่มีตัวช่วยจำเฉพาะสามารถแมปกับรหัสควบคุมในชุดอักขระอื่นได้
Huzzah! พกพา!
เกือบแล้ว ใน C ฉันสามารถเขียนprintf("\aHello, World!");
เสียงกริ่ง (หรือส่งเสียงบี๊บ) ที่ส่งเสียงข้อความ แต่ถ้าฉันต้องการพิมพ์บางอย่างในบรรทัดถัดไปฉันยังต้องรู้ว่าแพลตฟอร์มโฮสต์ต้องการย้ายไปที่บรรทัดถัดไปของเอาต์พุต CR LF CR? LF? NL? อื่น ๆ อีก? มากสำหรับการพกพา
C มีสองโหมดสำหรับ I / O: ไบนารีและข้อความ ในโหมดไบนารีข้อมูลอะไรก็ตามที่ถูกส่งจะได้รับการส่งตามสภาพ แต่ในโหมดข้อความมีการแปลแบบรันไทม์ที่แปลงอักขระพิเศษเป็นสิ่งที่แพลตฟอร์มโฮสต์ต้องการสำหรับบรรทัดใหม่ (และในทางกลับกัน)
เยี่ยมมากแล้วตัวละครพิเศษคืออะไร?
ดีที่การดำเนินการขึ้นอยู่กับเกินไป \n
แต่มีวิธีการดำเนินงานที่เป็นอิสระที่จะระบุว่า: โดยทั่วไปเรียกว่า "อักขระบรรทัดใหม่"
นี่เป็นจุดที่บอบบาง แต่สำคัญ: \n
ถูกแมป ณเวลารวบรวมกับค่าอักขระที่กำหนดการนำไปปฏิบัติซึ่ง (ในโหมดข้อความ) จะถูกแมปอีกครั้ง ณรันไทม์กับอักขระจริง (หรือลำดับของอักขระ) ที่ต้องการโดยแพลตฟอร์มพื้นฐานเพื่อย้าย ไปที่บรรทัดถัดไป
\n
แตกต่างจากตัวอักษรแบ็กสแลชอื่น ๆ ทั้งหมดเนื่องจากมีการแมปสองรายการที่เกี่ยวข้อง การทำแผนที่สองขั้นตอนนี้ทำให้\n
แตกต่างอย่างมีนัยสำคัญกว่าแม้กระทั่ง\r
ซึ่งเป็นเพียงการทำแผนที่รวบรวมเวลาเพื่อ CR (หรือรหัสควบคุมที่คล้ายกันมากที่สุดในสิ่งที่ชุดอักขระพื้นฐาน)
การเดินทางครั้งนี้ขึ้นโปรแกรมเมอร์ C และ C ++ มากมาย หากคุณต้องสำรวจ 100 คนอย่างน้อย 99 คนจะบอกคุณว่านั่น\n
หมายถึงการป้อนบรรทัด สิ่งนี้ไม่เป็นความจริงทั้งหมด การใช้งาน C และ C ++ ส่วนใหญ่ (อาจจะทั้งหมด) ใช้ LF เป็นค่ากลางเวทมนต์สำหรับ\n
แต่นั่นเป็นรายละเอียดการใช้งาน คอมไพเลอร์สามารถใช้ค่าอื่นได้ ในความเป็นจริงหากชุดอักขระโฮสต์ไม่ได้เป็นชุดของ ASCII (เช่นถ้าเป็น EBCDIC) ก็\n
จะไม่เป็น LF แน่นอน
ดังนั้นใน C และ C ++:
\r
คือการรับคืนอย่างแท้จริง\n
เป็นค่าเวทย์มนตร์ที่ได้รับการแปล (ในโหมดข้อความ) ณรันไทม์ไป / จากความหมายบรรทัดใหม่ของแพลตฟอร์มโฮสต์\r\n
มักจะเป็นข้อบกพร่องในการพกพา ในโหมดข้อความสิ่งนี้จะถูกแปลเป็น CR ตามด้วยลำดับบรรทัดใหม่ของแพลตฟอร์มซึ่งอาจไม่ใช่สิ่งที่ตั้งใจไว้ ในโหมดไบนารีสิ่งนี้จะถูกแปลเป็น CR ตามด้วยค่าเวทย์มนตร์ที่อาจไม่ใช่ LF - อาจไม่ใช่สิ่งที่ตั้งใจไว้\x0A
เป็นวิธีพกพาที่สุดในการระบุ ASCII LF แต่คุณต้องการทำในโหมดไบนารี การใช้งานในโหมดข้อความส่วนใหญ่จะปฏิบัติเช่น\n
นั้น\r\n
จริงแล้วเป็นวิธีเดียวที่ฉันสามารถแยกบรรทัดออกเป็นองค์ประกอบรายการแยกกันได้อย่างเหมาะสม มันทำให้ฉันสงสัยว่านี่เป็นสิ่งประดิษฐ์ HTML แปลก ๆ หรือว่าเกี่ยวข้องกับวิธีที่ Python นำสตริงจากrequest
วัตถุของฉัน
"\ n" => บรรทัดใหม่หรือ Linefeed (ซีแมนทิกส์)
ระบบที่ใช้ Unix ใช้เพียง "\ n" เพื่อวางบรรทัดข้อความ
\r
ใช้เพื่อชี้ไปที่จุดเริ่มต้นของบรรทัดและสามารถแทนที่ข้อความจากที่นั่นเช่น
main()
{
printf("\nab");
printf("\bsi");
printf("\rha");
}
สร้างเอาต์พุตนี้:
hai
\n
สำหรับบรรทัดใหม่
ในระยะสั้น \ r มีค่า ASCII 13 (CR) และ \ n มีค่า ASCII 10 (LF) Mac ใช้ CR เป็นตัวคั่นบรรทัด (อย่างน้อยก็เคยทำมาก่อนฉันไม่แน่ใจสำหรับ mac ที่ทันสมัย) * nix ใช้ LF และ Windows ใช้ทั้งสอง (CRLF)
นอกจากคำตอบของ @Jon Skeet:
ตามเนื้อผ้า Windows ได้ใช้ \ r \ n, Unix \ n และ Mac \ r อย่างไรก็ตาม Mac รุ่นใหม่ใช้ \ n เนื่องจากใช้เป็น unix
ใน C # ฉันพบว่าพวกเขาใช้ \ r \ n ในสตริง
\ r คือการรับคืนของสายการบิน; \ n เป็น New Line (Line Feed) ... ขึ้นอยู่กับระบบปฏิบัติการว่าแต่ละวิธีหมายถึงอะไร อ่านบทความนี้สำหรับข้อมูลเพิ่มเติมเกี่ยวกับความแตกต่างระหว่าง '\ n' และ '\ r \ n' ... ใน C.
ใช้เพื่อรับคืนรถ (ค่า ASCII คือ 13) \ n ใช้สำหรับบรรทัดใหม่ (ค่า ASCII คือ 10)
'\n'
ภาษาที่แตกต่างกันมีการตีความที่แตกต่างกันของ