Pokaż wyniki 1 do 4 z 4

Temat: PERL Splitowanie z wylaczeniem stringu pomiedzy danymi znakami

  1. #1
    Zarejestrowany
    Nov 2009
    Postów
    4

    Domyślnie PERL Splitowanie z wylaczeniem stringu pomiedzy danymi znakami

    Witam,

    Mam problem nad którym głowie się od dłuższego czasu. Mianowicie:

    mam tekst:

    $text = 'SAR001,"","Cimetrix, Inc","Bob Smith","CAM",N,8,1,0,7,"Error, Core Dumped" '

    chce go rozdzielic po separatorze , z wyłączeniem tekstu pomiedzy "".
    Posłużylem się takim sposobem:

    Kod:
    @new = ();
       push(@new, $+) while $text =~ m{
       "([^\"\\]*(?:\\.[^\"\\]*)*)",? # groups the phrase inside the quotes
        | ([^,]+),?
        | ,
       }gx;
       push(@new, undef) if substr($text,-1,1) eq ',';
    Wszystko jest ok z tym ze tekst chce otrzymac w postaci:

    Kod:
    "SAR001";"";"Cimetrix, Inc";"Bob Smith";"CAM";"N";"8";"1";"0";"7";"Error, Core Dumped";
    probowalem zastosowac:
    Kod:
    foreach my $val (@new) {
       
      print "\"$val\";";
      }
    Jednak ostatnia wartość w linice zapisywana jest ze nakiem końca lini w wyniku czego otrzymuje:


    Kod:
    "SAR001";"";"Cimetrix, Inc";"Bob Smith";"CAM";"N";"8";"1";"0";"7";"Error, Core Dumped
    ";
    Całkowite usunięcie znaku końca lini nie rozwiązuje problemu ponieważ $text w niektórych przypadkach jest wielo liniowy.
    Troche zagmatwane ale mam nadzieje ze ktos pomoze.
    Ostatnio edytowane przez dafian : 11-22-2010 - 13:58

  2. #2
    Zarejestrowany
    Jun 2006
    Skąd
    rand(.eu)
    Postów
    8,748

    Domyślnie

    Nie ma stracha...

    Kod:
    #!/usr/bin/perl
    $text = 'SAR001,"","Cimetrix, Inc","Bob Smith","CAM",N,8,1,0,7,"Error, Core Dumped"';
    
    @t = split /,/, $text;
    for ($c=0;$c<=$#t;$c++) {
    	if ($t[$c] =~ /^".*?[^"]$/) {
    		$t[$c] .= ",$t[$c+1]";
    		splice(@t,$c+1,1);
    	}
    }
    
    use Data::Dumper;
    print Dumper \@t;
    zwraca

    Kod:
    $VAR1 = [
              'SAR001',
              '""',
              '"Cimetrix, Inc"',
              '"Bob Smith"',
              '"CAM"',
              'N',
              '8',
              '1',
              '0',
              '7',
              '"Error, Core Dumped"'
            ];
    uzylem Data:umper bo pokazuje ladnie jaka jest struktura zmiennej, przydaje sie szczegolnie do wyswietlania w czytelnym formacie bardziej zaawansowanych struktur :-)
    ctrl-alt-del.cc - soft reset site for IT admins and other staff :-)

  3. #3
    Zarejestrowany
    Nov 2009
    Postów
    4

    Domyślnie

    Dzieki za odp ale nie do konca o to mi chodzilo. Sprobuje wyjaśnić lepiej.
    Mam plik wejściowy w formie:

    Kod:
    SAR001, ,"Cimetrix, Inc",Bob Smith,CAM,N,8,1,0,7,"Error, Core Dumped" 
    SAR002, ,"Cimetr22, In2",Bob2Smith,CA2,2,2,2,2,2,"Error,2Core Dumped"
    Natomiast forma pożądana przeze mnie to plik wyjściowy:

    Kod:
    "SAR001";"";"Cimetrix, Inc";"Bob Smith";"CAM";"N";"8";"1";"0";"7";"Error, Core Dumped"; 
    "SAR002";"";"Cimetr22, In2";"Bob2Smith";"CA2";"2";"2";"2";"2";"2";"Error, 2Core Dumped";
    Mam coś takiego:
    Kod:
    #!/usr/bin/perl
    
    open(DANE, "$ARGV[0]") || die "$ARGV[0] not exist";
    open(XXX, ">b-$ARGV[0]");
    
    
    
    
    while ($txt = <DANE>) 
    	{
    
    
    
     @new = ();
    push(@new, $+) while $txt =~ m{
     "([^\"\\]*(?:\\.[^\"\\]*)*)",? # groups the phrase inside the quotes
      | ([^,]+),?
       | ,
     }gx;
      push(@new, undef) if substr($txt,-1,1) eq ',';
    
    
    foreach my $val (@new) {
       
     print  XXX"\"$val\"\;";
      
    }
    }
    Jednak otrzymuje:


    Kod:
    "SAR001";" ";"Cimetrix, Inc";"Bob Smith";"CAM";"N";"8";"1";"0";"7";"Error, Core Dumped";"
    ";"SAR002";" ";"Cimetr22, In2";"Bob2Smith";"CA2";"2";"2";"2";"2";"2";"Error,2Core Dumped";"
    ";
    Wszystko ok z wyjatkiem tego ze ostatnia wartość jest ze znakiem konca lini przez co do kolejniej lini wskakuje mi "; .
    Mysle ze teraz jest troche jasniej.


    EDIT:

    W przypadku gdy wartość ostatnia w lini jest w " " skrypt wyrzuca:

    Kod:
    "SAR001";" ";"Cimetrix, Inc";"Bob Smith";"CAM";"N";"8";"1";"0";"7";"Error,Core Dumped";"<EOL>
    ";"SAR002";" ";"Cimetr22, In2";"Bob2Smith";"CA2";"2";"2";"2";"2";"2";"Error,2Core Dumped";"<EOL>
    ";
    Natomaist jezeli ostatnia wartość jest bez " " np.:

    Kod:
    SAR001, ,"Cimetrix, Inc",Bob Smith,CAM,N,8,1,0,7,Error,Core Dumped 
    SAR002, ,"Cimetr22, In2",Bob2Smith,CA2,2,2,2,2,2,Error,2Core Dumped
    skrypt wyrzuca:

    Kod:
    "SAR001";" ";"Cimetrix, Inc";"Bob Smith";"CAM";"N";"8";"1";"0";"7";"Error";"Core Dumped<EOL>
    ";"SAR002";" ";"Cimetr22, In2";"Bob2Smith";"CA2";"2";"2";"2";"2";"2";"Error";"2Core Dumped<EOL>
    ";
    Wydaje mi sie ze rozwiazaniem jest zastapienie "<EOL>"; na <EOL>
    oraz <EOL>"; na ";<EOL>

    niestety:
    $val =~ s/\"\n\"\;/\n/m
    to nie to.
    Ostatnio edytowane przez dafian : 11-23-2010 - 11:29

  4. #4
    Zarejestrowany
    Jun 2006
    Skąd
    rand(.eu)
    Postów
    8,748

    Domyślnie

    Kod:
    #!/usr/bin/perl
    while (<DATA>) {
    	chomp;
    	@t = split /,/, $_;
    	for ($c=0;$c<=$#t;$c++) {
    		if ($t[$c] =~ /^".*?[^"]$/) {
                            # sklejamy pola ktore maja przecinki w srodku
    			unless ($t[$c] =~ /"$/) {
    				$t[$c] .= ",$t[$c+1]";
    				splice(@t,$c+1,1);
    			}
    		} elsif ($t[$c] !~ /^".*?"$/) {
                            # pole nie jest w cudzyslowach wiec dodajemy je
    			$t[$c] = "\"$t[$c]\"";
    		}
    	}
            # polacz pola w jedna linijke i dodaj newline na koncu (ale bez ; na koncu)
    	print join (';', @t) . "\n";
    }
    
    __DATA__
    SAR001, ,"Cimetrix, Inc",Bob Smith,CAM,N,8,1,0,7,"Error, Core Dumped" 
    SAR002, ,"Cimetr22, In2",Bob2Smith,CA2,2,2,2,2,2,"Error,2Core Dumped"
    dziala dokladnie jak chciales

    Kod:
    "SAR001";" ";"Cimetrix, Inc";"Bob Smith";"CAM";"N";"8";"1";"0";"7";"Error, Core Dumped" 
    "SAR002";" ";"Cimetr22, In2";"Bob2Smith";"CA2";"2";"2";"2";"2";"2";"Error,2Core Dumped"
    Ostatnio edytowane przez TQM : 11-23-2010 - 16:22
    ctrl-alt-del.cc - soft reset site for IT admins and other staff :-)

Zasady Postowania

  • Nie możesz zakładać nowych tematów
  • Nie możesz pisać wiadomości
  • Nie możesz dodawać załączników
  • Nie możesz edytować swoich postów
  •  
Subskrybuj