Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked

Splitting a string in Perl

by gzayzay (Sexton)
on Apr 25, 2008 at 20:25 UTC ( #682907=perlquestion: print w/replies, xml ) Need Help??
gzayzay has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks

I am trying to split a string into three parts. However, I am finding it difficult to come up with the appropriate pattern to help me split this string. Hence, could any monk kindly him me figure this out?

-MEMADDR- ----HEX REPRESENTATION---- ---ASCII--- 0000 21 74 63 5f 37 5f 31 5f 36 !tc_7_1_6

my($memAddr, $data, $ascii); open(DATAFILE $filename) while(<DATAFILE>) { my $line = $_; ($memAddr, $data, $ascii) = split(/PATTERN/, $line);
I am trying to get a pattern the will result to me having the following values

$memAddr = 0000; $data = 2174635f375f315f36; # I think I need join() to get this for +mat $ascii = !tc_7_1_6

I will highly appreciate a help for any Monk out there.

Replies are listed 'Best First'.
Re: Splitting a string in Perl
by dragonchild (Archbishop) on Apr 25, 2008 at 20:39 UTC
    That looks to be a fixed-width representation. That is better handled using unpack instead.
    my ($memAddr, $data, $ascii) = unpack( "A10A20A*", $line );
    I guessed at the 10 and 20, but those are the column widths. The * means "and everything else".

    Then, you will want to massage in some fashion the various bits. So, something like $data =~ s/\s//g; to remove the whitespaces. Etc.

    My criteria for good software:
    1. Does it work?
    2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
Re: Splitting a string in Perl
by gamache (Friar) on Apr 25, 2008 at 20:32 UTC
    my ($memAddr, $data, $ascii) = split /\s{2,}/, $line; # split line at + 2+ spaces $data =~ s/ //g; # remove whitespace from $data chomp $ascii; # remove EOL from $ascii
      Thanks, your're my hero.. It works exactly as I wanted it
Re: Splitting a string in Perl
by holli (Monsignor) on Apr 25, 2008 at 20:43 UTC
    print join ('*', unpack 'A4x7A26x8A*', '0000 21 74 63 5f 37 5f 3 +1 5f 36 !tc_7_1_6');

    holli, /regexed monk/
Re: Splitting a string in Perl
by FunkyMonk (Canon) on Apr 25, 2008 at 20:37 UTC
    You're going to have a hard time using split to split this line (what if the hex is 20 20 20 - that'll give 3 spaces in ASCII, or what if the length of the data isn't a multiple of nine). You'll be better of using unpack.

    Unless I state otherwise, my code all runs with strict and warnings

      Good catch! To make a split solution work here, you'd need the optional third argument.

      use Data::Dumper; my $in = '0000 21 20 20 20 20 20 20 20 36 ! 6'; my @out = split /\s{2,}/, $in, 3; print Dumper \@out; __END__ $VAR1 = [ '0000', '21 20 20 20 20 20 20 20 36', '! 6' ];
Re: Splitting a string in Perl
by johngg (Abbot) on Apr 25, 2008 at 21:08 UTC
    I agree with other Monks that unpack is the way to go but if you are more comfortable with split I would use that in combination with splice and join in stages. Something like (not tested)

    my @flds = split m{\s+}, $line; my $memAddr = splice @flds, 0, 1; my $ascii = splice @flds, -1, 1; my $data = join q{}, @flds;

    I hope this is useful.



Re: Splitting a string in Perl
by ww (Archbishop) on Apr 25, 2008 at 20:55 UTC
    Your /PATTERN/ appears to be whitespace (/s+).

    Answers re split (and, as it happens, re join) can be found at perldoc -f split.

    Working code (to your specs, except for using __DATA__ rather than a file as the data source):

    #!/usr/bin/perl use strict; use warnings; my($memAddr, $data, $ascii, @lines, $line); # open(DATAFILE $filename) # while(<DATAFILE>) @lines = <DATA>; for $line(@lines) { chomp $line; ($memAddr, $data, $ascii) = split(/\s\s+/, $line); $data = join('', split(/\s/, $data)); print "$memAddr $data $ascii \n"; } __DATA__ -MEMADDR- ----HEX REPRESENTATION---- ---ASCII--- 0000 21 74 63 5f 37 5f 31 5f 36 !tc_7_1_6 1234 0f bb ac 11 a6 82 ff 5f 27 !xy_8_1

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://682907]
Approved by ww
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (3)
As of 2017-04-27 06:42 GMT
Find Nodes?
    Voting Booth?
    I'm a fool:

    Results (501 votes). Check out past polls.