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

Lets presume i have a text like "Ipod batteries for Apple Ipod PDAs. Replacement batteries from Laptops for Less.com.url" in scalar $name. Now i don't want to display this string this long, i'd like to shorten it instead. To be more specific, i want to display only 1 - 20 characters and no more. I tried using
$_ = "Ipod batteries for Apple Ipod PDAs. Replacement batteries from L +aptops for Less.com.url"; /^(.{1, 20}).*/; $shortened_string = $1;
but that doesn't work? I think this is common procedure for a lot of forums to shorten long URLs, but i have not found suitable snippet for my own use yet.

Replies are listed 'Best First'.
Re: how to shorten given string?
by Yendor (Pilgrim) on Oct 13, 2004 at 18:44 UTC
      What if i want to do it with regexp, is there a way to do it like that?

        Your posted code will work if you remove the space after the comma in your regex.

        /^(.{1, 20}).*/; # doesn't work /^(.{1,20}).*/; # does work /^(.{1,20})/; # even easier
        May the Force be with you

        Yes, but why? It works fine, but substr is quicker and easier to understand.

        my $short = ( m/^(.{1,20})/ ) ? $1 : '';

        ...or...

        my( $short ) = m/^(.{0,20})/;

        Dave

        What if i want to do it with regexp, is there a way to do it like that?
        What if I was given a perfectly good working solution, and then I said "No, I want to do it some other way"? Would people think I was asking a homework question? Maybe. Maybe not.

        In any event, if this wasn't a homework question, you should have given more background about why substr didn't suffice, so that we know why you rejected that solution.

        And it looks like I'm not the only one who wonders this.

        -- Randal L. Schwartz, Perl hacker
        Be sure to read my standard disclaimer if this is a reply.

        Others here are better (and faster) with regexps than I. They have provided answers below. My question to you would be:
        What is the reason for wanting to use a regex to perform a substr on a string when there's a substr function already?

Re: how to shorten given string?
by davido (Cardinal) on Oct 13, 2004 at 18:47 UTC

    The answer to that question depends entirely on what you consider to be the significant portion of the original string; the portion that you can't afford to lose.

    Your example script attempts to just truncate the source string at 20 characters. You can do that quickly like this:

    my $short_string = substr $_, 0, 20;

    But that truncates your string to become: "Ipod batteries for A". Are you ok with that? Or do you need to define a more complex set of rules as to how the original string should be shortened?


    Dave

Re: how to shorten given string?
by fglock (Vicar) on Oct 13, 2004 at 20:16 UTC

    By the way, there is a package that does this:

    use String::Escape; print String::Escape::elide( "Ipod batteries for Apple Ipod PDAs. Repl +acement batteries from Laptops for Less.com.url", 20 ); # Ipod batteries...
Re: how to shorten given string?
by borisz (Canon) on Oct 13, 2004 at 18:49 UTC
    Here are two solutions:
    $_ = "Ipod batteries for Apple Ipod PDAs. Replacement batteries from L +aptops for Less.com.url"; print substr ($_, 0, 20); /^(.{0,20})/; print $1;
    Boris
Re: how to shorten given string?
by ysth (Canon) on Oct 13, 2004 at 18:55 UTC
    /^(.{1, 20}).*/; $shortened_string = $1;
    but that doesn't work?
    That should work, though the .* is useless and you ought to make sure the match succeeds before using $1: $shortened_string = /^(.{1,20})/ && $1; or even skip using $1 at all: ($shortened_string) = /^(.{1,20})/; (though the match can only fail if the string is empty or undef.)  Go back and try it again and make sure that you didn't have something else wrong to make it appear not to work.
Re: how to shorten given string?
by TedPride (Priest) on Oct 13, 2004 at 19:29 UTC
    my $str = '1234 6789 1234 6789 1234 6789 '; my $printstr = substr($str, 0, 20+1); $printstr =~ s/\W+\w*$//; print $printstr;
    Unless I'm missing something important, this should cut the line at the right spot. Note that it's 20+1 because the length has to be max length + 1 so it won't cut a word that fits entirely into the string.

    EDIT: You may have to change the regex if words can include characters other than \w, such as .