Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Splitting each word in a string

by chaskins (Sexton)
on Jun 26, 2001 at 14:36 UTC ( [id://91542]=perlquestion: print w/replies, xml ) Need Help??

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

I have a string I need to split up and store each word as a new variable. I've tries using the 'split' command, but the problem here is that the white spaces vary in size. Does anyone know how I could do this? Here is an example of the string;
Pid    DenyMode   R/W        Oplock           Name
Thanks Chris

Replies are listed 'Best First'.
Re: Splitting each word in a string
by busunsl (Vicar) on Jun 26, 2001 at 14:40 UTC
    Split takes a regex as delimiter, so you can use:
    my @words = split /\s+/, $string;
Re: Splitting each word in a string
by ariels (Curate) on Jun 26, 2001 at 14:43 UTC
    This is special-cased in split ' ', $string (see split documentation).

    Doesn't

    @x = split ' ',
           q(Pid    DenyMode   R/W        Oplock           Name);
    
    do what you want?
      Yep, sorry I was not thinking this morning :( DOH! Chris
Re: Splitting each word in a string
by azatoth (Curate) on Jun 26, 2001 at 14:43 UTC
Re: Splitting each word in a string
by grinder (Bishop) on Jun 26, 2001 at 19:59 UTC

    I smell the parsing of smbstatus -L, looking for file locks on Samba-mounted drives...

    The use of split isn't quite enough, should you (like me) happen to have users who create file names with spaces. You have to do it in two parts, working forwards and backwards to isolate the file name. I have some ugly code to do this.

    Warning: ugly code ahead!

    This is not at all bullet-proof, but feel free to adapt the nuggets to do something better.

    #! /usr/bin/perl -w use strict; open IN, '/usr/local/bin/smbstatus -L 2>/dev/null |' or die "Cannot open input pipe from smbstatus: $!\n"; while( <IN> ) { chomp; last if /^-*$/; } while( <IN> ) { chomp; my( $pid, $mode, $rw, $oplock, $rest ) = split(' ', $_, 5); my( $name, $dayname, $mon, $day, $timestamp, $year ) = ($rest =~ /(.*?)\s+(\S{3})\s+(\S{3})\s+(\d+)\s+(\d+:\d+:\d+)\s ++(\d+)$/); last unless defined $pid; print "[$pid] [$name]\n"; }

    I hacked this up ages ago. I guess I should dust it off and make it a little cleaner. When I get a round tuit.


    --
    g r i n d e r
Re: Splitting each word in a string
by mrmick (Curate) on Jun 26, 2001 at 17:04 UTC
    While this can be done, you may want to look here, here, or here to see why you may not want to do things this way.

    Mick
Re: Splitting each word in a string
by khota (Initiate) on Jun 26, 2001 at 18:50 UTC
    You can use split (/ +/,$string); The + meaning that you want to consider one or more spaces as separators.
Re: Splitting each word in a string
by thatguy (Parson) on Jun 26, 2001 at 18:51 UTC
    or you could even do:

    my @string="Pid DenyMode R/W Oplock Name"; foreach (@string) { my ($pid,$deny,$rw,$oplock,$name) = split; # do something here }
    yeah, it's big.
Re: Splitting each word in a string
by IraTarball (Monk) on Jun 26, 2001 at 20:45 UTC
    I know you've already figured this out but, doesn't split use \s+ by default? So...
    chomp ($line = <FH>); @vars = split $line;
    Get's you the strings to use for whatever evil purposes you might have.

    "So... What do all these little arrows mean?"
    ~unknown

      Well, yeah, split uses /\s+/ by default - sort of. However, the first argument, if any, of split is the regular expression. Only if the first argument is missing, it results to the default. In your example, which of course you haven't tested, you give split one argument. One argument split will split $_, using the regular expression given - in your case, the value of $line. Which is not at all what you want.

      I said "sort of", meaning that the default case (that is, no arguments to split) trailing empty fields are removed - just like in awk. Which doesn't happen if you use /\s+/ as first argument. Use ' ' to get the effect of the default behaviour.

      You know, you would have saved a lot of trouble, from both you and me (and people who thought you spoke the truth and used your suggestion) if you had either tried out your suggestion or had consulted the manual page. But I guess a quick typing without thinking is the fast lane to fame.

      -- Abigail

        trailing empty fields are removed - just like in awk. Which doesn't happen if you use /\s+/ as first argument

        No, the default case is different from /\s+/ in that a leading empty field is ignored. The only way to get Perl to not strip trailing empty fields is to pass a 3rd argument to split, usually -1.

        I won't complain about you having wasted my time by getting this wrong. This isn't comp.lang.perl.* and most of us like it that way. If you want to complain about people wasting your time, then comp.lang.perl.* is probably a better forum for you.

        We're all here to have fun and there are plenty of us to answer questions quite correctly as well as incorrectly (and lots of shades of grey in between) and then discuss the results. Many of us end up learning a lot of Perl in the process, but such isn't the only purpose.

        Sure, checking your answers before you post is prudent and polite, but so is not grousing at people when they make a mistake.

        Have the appropriate amount of fun...

                - tye (but my friends call me "Tye")
        Of course you're right about split. My fingers went faster than my brain. I didn't know about the difference between /\s+/ and ' '. In fact Programming Perl seems to indicate that these are equivalent, but checking perldoc I can see that they are not.

        Saved 'a lot' of trouble? Really? Did this take that much time? As for others thinking I was authoritative, I thought my posting was phrased in a questioning way. Sometimes replies are for the edification of the replier as well. Any way, I don't know about you but I wouldn't blindly implement solutions posted by random contributors (especially lowly acolytes ;-) without running a couple of test cases first.

        Well, I'll continue typing as fast as I can and maybe some day I'll get one right.

        Thanks,
        Ira

        "So... What do all these little arrows mean?"
        ~unknown

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://91542]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (3)
As of 2024-04-20 00:08 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found