Renyulb28 has asked for the wisdom of the Perl Monks concerning the following question:

I would like to know how I can read a text file that has lines of 1's, 2's, and 0's going two characters at a time. For example, a line may look like 2 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 and then making each '1 1' as 0, either '1 2' or '2 1' as 1, and '2 2' as 2, and then any pair with a 0 in it as -1 (ie '0 1') I have tried the search and replace function, but that does not do so well with going by 2 characters at a time per line, so it all messes up. Thank you
  • Comment on Reading lines going by 2 characters at a time

Replies are listed 'Best First'.
Re: Reading lines going by 2 characters at a time
by moritz (Cardinal) on Mar 17, 2011 at 16:06 UTC
Re: Reading lines going by 2 characters at a time
by wind (Priest) on Mar 17, 2011 at 16:07 UTC
    Just make a regular expression to process each line two characters at a time, and then translate.
    my %translate = ( '0 0' => -1, '0 1' => -1, '0 2' => -1, '1 0' => -1, '1 1' => 0, '1 2' => 1, '2 0' => -1, '2 1' => 1, '2 2' => 2, ); while (<$fh>) { s/(\d \d)/$translate{$1}/g; print "New line: $_"; }
    And just for kicks, here is more obfuscated, but purely mathematical solution for the translation
    while (<DATA>) { s{(\d)\s+(\d)}{log(($1 * $2) || (1/2)) / log(2)}eg; print "New line: $_"; } __DATA__ 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 2 0 1 0 1 0 1 0 1 1 1 2 2 0 2 0 2 0 2 0 2 1 2 1 1 1 0 1 0 1 0 1 0 1 2 1 2 1 1 1 1 1 1 1 1 1 2 2 2 1 2 1 2 1 2 1 2 2 2 1 1 2 0 2 0 2 0 2 0 2 2 1 2 2 1 2 1 2 1 2 1 2 2 2 2 2 2 2 2 2 2 2 2
    Outputs
    New line: 0 0 -1 -1 -1 -1 New line: 0 1 -1 -1 -1 -1 New line: 0 2 -1 -1 -1 -1 New line: 1 0 -1 -1 -1 -1 New line: 1 1 0 0 0 0 New line: 1 2 1 1 1 1 New line: 2 0 -1 -1 -1 -1 New line: 2 1 1 1 1 1 New line: 2 2 2 2 2 2
    - Miller
Re: Reading lines going by 2 characters at a time
by kennethk (Abbot) on Mar 17, 2011 at 16:11 UTC
    You say you "tried the search and replace function" (I can only assume you mean a substitution regex), but don't show your work. It's a whole lot easier for us to help fix your code if you show us your code. Read How (Not) To Ask A Question.

    Assuming your input has not been mangled by lack of <code> tags (Markup in the Monastery), you can iterate over the set with a while loop and a regular expression. It might look something like:

    #!/usr/bin/perl use strict; use warnings; $_ = '2 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2'; while (/(\d) (\d)/g) { my ($first, $second) = ($1, $2); # insert logic for output }

    See Global matching in perlretut.