ในภาษา Perl ฉันจะเข้าร่วมบรรทัดอินพุตกับบรรทัดถัดไปได้อย่างไรหากบรรทัดแรกลงท้ายด้วยเครื่องหมายโคลอน

เส้นของฉัน:

ABC: XYZ
XYZ ABC: XYZ
XYZ:
ABC
XYZ
ABC:
AAB
CCD

ฉันต้องการรวมบรรทัดที่ลงท้ายด้วยโคลอน โดยมีบรรทัดถัดไป:

ABC: XYZ
XYZ ABC: XYZ
XYZ: ABC
XYZ
ABC: AAB
CCD

person user935420    schedule 05.11.2011    source แหล่งที่มา
comment
@Sinan คุณพูดถูก แต่ช่างเป็นคำตอบที่ไม่ดีเลย   -  person tchrist    schedule 05.11.2011
comment
@tchrist อย่างที่ฉันสงสัย หากสิ่งเหล่านี้เป็นการบ้านหรือคำถามสัมภาษณ์ คำตอบที่แย่กว่านั้นอาจจะดีกว่า ;-)   -  person Sinan Ünür    schedule 05.11.2011
comment
@sinan chutzpah ของเด็ก ๆ ที่ขอให้คนอื่นทำการบ้านให้พวกเขาทำให้ฉันตะลึง นี่เป็นเหตุให้ถูกไล่ออกตอนที่ฉันอยู่ที่มหาวิทยาลัย และไม่มีช่องทางให้อุทธรณ์ได้ คุณทำงานของคุณเองแล้ว สิ่งอื่นใดคือการโกง   -  person tchrist    schedule 05.11.2011


คำตอบ (5)


หากเนื้อหาพอดีกับหน่วยความจำ ให้โหลดเนื้อหานั้นลงในตัวแปรเดียวแล้วทำดังนี้

$text =~ s/:\n/: /g
person Marcelo Cantos    schedule 05.11.2011
comment
แม้ว่าเนื้อหาจะสามารถใส่ในหน่วยความจำได้ แต่การพูดเสียงดังถือเป็นคำตอบที่ผิดในเกือบ 99.99% ของกรณี - person Sinan Ünür; 05.11.2011
comment
99.99% ของคดี? โดยส่วนตัวแล้วฉันจะทำทุกอย่างที่เกี่ยวข้องกับการพิมพ์น้อยลง มันผิดเหรอ? - person Literat; 05.11.2011
comment
@DanDman ความเกียจคร้านเท็จไม่ใช่คุณธรรม เขียนอัลกอริธึมที่ขยายขนาด ไม่ใช่อันที่ระเบิด - person tchrist; 05.11.2011
comment
@tchrist tchrist -- ขงจื๊อแห่งเพิร์ล - person TLP; 05.11.2011

หากคุณต้องการแก้ไขไฟล์ ให้ใช้บรรทัดคำสั่งนี้:

% perl -i.orig -pe 'chomp if /:$/' yourfile

หากคุณอยู่ในลูปอินพุตและต้องการรวบรวมข้อมูลที่ลงท้ายด้วยโคลอน ให้ทำดังนี้

while (<>) {
    chomp;
    if (/:$/ && !eof) {
         $_ .= <>;
         redo unless eof;
    }
    # now you have your cuddled line(s), proceed as before
    ...
}

นี่ถือว่าบรรทัดสุดท้ายของไฟล์ของคุณไม่ใช่บรรทัดต่อ

person tchrist    schedule 05.11.2011
comment
สมมติฐานอันยิ่งใหญ่เนื่องจากมันจะเข้าสู่วงวนไม่สิ้นสุดหากบรรทัดสุดท้ายต่อเนื่องกัน! รักหนึ่งซับแม้ว่า - person Bill Ruppert; 05.11.2011
comment
@Bill นั่นเป็นเหตุผลที่ฉันพูดถึงข้อสันนิษฐาน ปริมาณ unless eof แบบเสรีนิยมจะช่วยดูแลสิ่งนั้นได้ แต่มันไม่มีประโยชน์มากนักสำหรับ tty - person tchrist; 05.11.2011
comment
เพียงแค่ต้องการทำซ้ำเว้นแต่ว่า eof; - person Bill Ruppert; 05.11.2011
comment
ไม่ใช่กรณีของ eof ในกรณีที่ครอบคลุมในขณะนั้นใช่หรือไม่ - person Bill Ruppert; 06.11.2011
comment
แทนที่จะมีความซับซ้อนทั้งหมดนี้ สิ่งที่เรียบง่าย: (ก) แทนที่โคลอน-ขึ้นบรรทัดใหม่ด้วยโคลอน-สเปซ; (ข) พิมพ์ - person FMc; 06.11.2011
comment
@Bill: ไม่ ในขณะที่ไม่ครอบคลุมถึงกรณี eof พิจารณาบรรทัดสุดท้ายของไฟล์เช่นเคย - person tchrist; 06.11.2011

ความพยายามของฉันในเวอร์ชันที่สวยงามยิ่งขึ้น

while (<DATA>) {
  chomp;
  print $_;
  print /:$/ ? " " : "\n";
}

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

#!/usr/bin/env perl

use strict;
use warnings;

my $text;
while( my $line = <DATA> ) {
  if ($line =~ /:\s*\n/ && defined $text) {
      print $text;
      undef $text;
  }
  $line =~ s/:\s*\n/: /g;
  $text .= $line;
}
print $text if defined $text;

__DATA__
ABC: XYZ
XYZ ABC: XYZ
XYZ:
ABC
XYZ
ABC:
AAB
CCD
person Bill Ruppert    schedule 05.11.2011
comment
คุณมี regex เดียวกันในสองแห่ง ดูเหมือนซับซ้อนมาก - person tchrist; 05.11.2011
comment
พยายามความถูกต้องและหน่วยความจำน้อยที่สุดมากกว่าความเรียบง่าย - person Bill Ruppert; 05.11.2011
comment
ความเรียบง่ายนำมาซึ่งความชัดเจน ในอัลกอริธึมเช่นเดียวกับในการพิสูจน์อักษร ยิ่งเรียบง่ายและสะอาดตาเท่าไรก็ยิ่งมีความสวยงามมากขึ้นเท่านั้น ทำไมคุณถึงมีสองตัวแปร? เหตุใดจึงต้องใช้ตัวแปรตัวสะสมมากกว่าหนึ่งตัว - person tchrist; 05.11.2011
comment
ฉันเริ่มต้นด้วยโค้ดที่คัดลอกมาจากด้านล่างและทำการเปลี่ยนแปลงเพียงเล็กน้อย ฉันต้องการข้อความที่สร้างขึ้นเพื่อรอการพิมพ์และบรรทัดที่เข้ามาซึ่งอาจเพิ่มลงในบรรทัดเอาต์พุตปัจจุบันหรือใช้เพื่อเริ่มบรรทัดเอาต์พุตใหม่ ฉันขี้เกียจใช้สถานะ undef ของ $text เป็นตัวแปรสถานะ - person Bill Ruppert; 05.11.2011

คำแนะนำทั้งสองจนถึงตอนนี้แนะนำให้แนบไฟล์ลงในหน่วยความจำ แต่ไม่จำเป็นอย่างยิ่งหากมีคำถามเดิม

#!/usr/bin/env perl

use strict;
use warnings;

my $text;
while( my $line = <DATA> ) {
    if ($line =~ s/ : \s+ \z /: /x) {
        $text .= $line;
    }
    else {
        print $text if is_nonempty_string($text);
        print $line;
        $text = '';
    }
}

print $text, "\n" if is_nonempty_string($text);

sub is_nonempty_string { defined($_[0]) and length($_[0]) }

__DATA__
ABC: XYZ
XYZ ABC: XYZ
XYZ:
ABC
XYZ
ABC:
AAB
CCD:
person Joel Berger    schedule 05.11.2011
comment
พิมพ์บนอินพุตว่าง เก็บเอาต์พุตทั้งหมดไว้ในหน่วยความจำ - person Bill Ruppert; 05.11.2011
comment
ฉันพยายามปรับปรุงวิธีแก้ปัญหาแบบเดิมโดยไม่เปลี่ยนจิตวิญญาณของมัน รู้สึกอิสระที่จะย้อนกลับการเปลี่ยนแปลง - person Sinan Ünür; 05.11.2011
comment
โอเค ฉันเดาว่าเช้านี้ฉันจะไปเร็วหน่อย ขอบคุณสินัน. ดูเหมือนว่างานนี้ควรจะง่ายกว่านี้ - person Joel Berger; 05.11.2011
comment
แม้ว่าความจริงแล้วสิ่งที่ป้อนข้อมูลที่ว่างเปล่าไม่ได้ทำให้ฉันกังวล สิ่งนี้ดูเหมือนจะเกิดขึ้นเพียงครั้งเดียว ดังนั้นสมมติว่ามันถูกใช้เพื่อบางสิ่งบางอย่าง ไม่ต้องพูดถึง งานพิมพ์มีไว้เพื่อจัดแสดง ไม่ใช่การใช้งานขั้นสุดท้าย หาก OP ต้องการการแก้ไขแบบถาวร ให้พวกเขาลองดู ดูเหมือนว่ากรณี Edge จะมีอยู่มากมาย - person Joel Berger; 06.11.2011

person    schedule
comment
คำถามเหล่านี้ถูกวางไม่ดี เนื่องจากไม่สามารถระบุได้ว่าพวกเขาต้องการเพียงโปรแกรมเล็กๆ น้อยๆ เพื่อรวมบรรทัดต่อเนื่องเป็นตัวกรองหรือตัวจัดการไฟล์ หรือไม่ว่าจะเป็นจริง ๆ แล้วเป็นการถามถึงวิธีแก้ไขลูปอินพุตที่มีอยู่เพื่อพิจารณาตามที่กล่าวมา ความต่อเนื่อง - person tchrist; 05.11.2011