http://www.perlmonks.org?node_id=989455

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

Hi perl monks, I was wondering if someone could help me with the following, i have the following string as an example: Apple iPhone 4 Black Cover (keeping in mind I have various different strings) Is it possible to retain the first 4 characters for each word? separated by a hyphen i.e to display the following: Appl-iPho-4-Blac-Cove Please can someone help me? Thank you :)

Replies are listed 'Best First'.
Re: Retain first 4 characters of a string
by johngg (Canon) on Aug 24, 2012 at 09:19 UTC
Re: Retain first 4 characters of a string
by nemesdani (Friar) on Aug 24, 2012 at 09:05 UTC
    1. You can split by space and process every word.
    2. You can capture the first 4 characters between word boundaries (\b) globally.

    I'm too lazy to be proud of being impatient.
Re: Retain first 4 characters of a string
by uday_sagar (Scribe) on Aug 24, 2012 at 09:57 UTC

    perlnoobster,

    I just added flavors to your dish so that it is eatable and delicious!

    $phn = "Apple iPhone 4 Black Cover"; print $trim = join '-', (map { substr($_, 0, 4) } split /\s+/, $phn);
      Perfect, it is indeed eatable and very delicous! Thank you to everyone that had a hand in helping me, i really appreciate it :)
      Sagar, the code works perfectly fine however is it possible to retain model numbers? e.g
      Apple iPhone x41212 Black Cover
      so even if its a mixture of a model number and letter the split would retain it as is? Thank you :)
        Yes , it is possible -- how would you do it? Please describe the steps in english

        I didnt get you exactly. Do you want to conserve (not trimming to 4 letters) the string "x41212"? (model number)

Re: Retain first 4 characters of a string
by Anonymous Monk on Aug 24, 2012 at 09:05 UTC
    Sure, if you can start writing that program, I'll finish it for you
      Hello anon monk :) I've conjured up the following and am trying to work with it:  my $trim = join ' ', (split /\s+/, $phn)[0..1]; it retains the word and not the first characters of each word though :( Please can you help?

        And here it is, a bunch

        #!/usr/bin/perl -- use strict; use warnings; use 5.010; use Data::Dumper::Names; my $orig = 'Apple iPhone 4 Black Cover'; my $want = 'Appl-iPho-4-Blac-Cove'; say Dumper $orig, $want; my $trim = join ' ', (split /\s+/, $orig)[0..1]; say Dumper $trim; say "THE PROBLEM WITH YOUR ATTEMPT IS RETURN VALUE OF SPLIT ", Dumper( +[ split /\s+/, $orig ]); say "OF WHICH YOU ONLY TAKE FIRST 2 ", Dumper([ (split /\s+/, $orig)[0 +..1] ]); say "YOU NEED MATCH OPERATOR AND MAP AS WELL"; $trim = join '-', map { /^(\w{1,4})/ } split /\s+/, $orig; say Dumper $want, $trim ; say "SAME THING USING SUBSTITUTION OPERATOR"; $trim = $orig; $trim =~ s{ (?: (\w{1,4}) # capture first 1-to-4 word chars in $1 \w* # match and ignore any remaining words ) | # or (\s+) # any save any-amount-of-whitespace into $2 }{ defined $2 # if defined $2 ? '-' # then return '-' : $1; # else return $1 }gex; say Dumper $want, $trim ; $trim = $orig; say "AND MAYBE FASTER, first transliterate spaces into -"; $trim =~ tr/\t\r\n /-/s; say Dumper $trim; say "then shorten words to 4 chars using perl 5.10 feature \\K"; $trim =~ s{\w{4}\K\w*}{}g; # ignore first 4 word chars, delete others say Dumper $want, $trim ; say "USING MATCH OPERATOR ONLY "; $trim = join '-', $orig =~ m{(\w{4})\w*\b|(\w{1,3})}g; say Dumper $want, $trim ; say "THOSE CAPTURE GROUPS ARE TRICKY "; $trim = join '-', grep defined, $orig =~ m{(\w{4})\w*\b|(\w{1,3})}g; say Dumper $want, $trim ; __END__ $ perl trim.pl $orig = 'Apple iPhone 4 Black Cover'; $want = 'Appl-iPho-4-Blac-Cove'; $trim = 'Apple iPhone'; THE PROBLEM WITH YOUR ATTEMPT IS RETURN VALUE OF SPLIT $VAR1 = [ 'Apple', 'iPhone', '4', 'Black', 'Cover' ]; OF WHICH YOU ONLY TAKE FIRST 2 $VAR1 = [ 'Apple', 'iPhone' ]; YOU NEED MATCH OPERATOR AND MAP AS WELL $want = 'Appl-iPho-4-Blac-Cove'; $trim = 'Appl-iPho-4-Blac-Cove'; SAME THING USING SUBSTITUTION OPERATOR $want = 'Appl-iPho-4-Blac-Cove'; $trim = 'Appl-iPho-4-Blac-Cove'; AND MAYBE FASTER, first transliterate spaces into - $trim = 'Apple-iPhone-4-Black-Cover'; then shorten words to 4 chars using perl 5.10 feature \K $want = 'Appl-iPho-4-Blac-Cove'; $trim = 'Appl-iPho-4-Blac-Cove'; USING MATCH OPERATOR ONLY Use of uninitialized value $orig in join or string at trim.pl line 42. Use of uninitialized value $orig in join or string at trim.pl line 42. Use of uninitialized value $orig in join or string at trim.pl line 42. Use of uninitialized value $orig in join or string at trim.pl line 42. Use of uninitialized value $orig in join or string at trim.pl line 42. $want = 'Appl-iPho-4-Blac-Cove'; $trim = 'Appl--iPho---4-Blac--Cove-'; THOSE CAPTURE GROUPS ARE TRICKY $want = 'Appl-iPho-4-Blac-Cove'; $trim = 'Appl-iPho-4-Blac-Cove';