Loading ...
Sorry, an error occurred while loading the content.

Need another method to achieve the task.

Expand Messages
  • Sreeram B S
    Hello friends, I have one task to be achieved. The task is as follows: (a) Ask for user to input a long word having _ (underscore) embedded in it. (b) Now,
    Message 1 of 5 , Dec 1, 2005
    • 0 Attachment
      Hello friends,
      I have one task to be achieved. The task is as
      follows:

      (a) Ask for user to input a long word having '_'
      (underscore) embedded in it.
      (b) Now, the program has to capitalise the first
      letter found after each '_'.
      (c) The program also has to capitalise the first
      letter of the word.

      I could achieve this, but in a somewhat complex way.
      My code looks like this:

      ===================================================

      --------------------------------------------------
      #!/usr/bin/perl


      my @tmp;
      print ("Input string: ");
      chomp ( $tmp = <STDIN> );
      @tmp = split(/_/, $tmp);
      $_ = "\u$_" foreach (@tmp);
      $tmp = join('_', @tmp);
      print ("Modified version = $tmp\n");
      -------------------------------------------------

      Upon execution: [The first '$' in lines 1 and 4 is the
      Unix-Prompt].
      $ perl test.p
      Input string: how_are_u
      Modified version = How_Are_U
      $

      ===================================================

      My Question: Is there any simpler method to achieve
      the above task?
      If the simpler method exists, kindly suggest.

      Thanks and Regards,
      Sreeram








      __________________________________
      Yahoo! Mail - PC Magazine Editors' Choice 2005
      http://mail.yahoo.com
    • Jeff 'japhy' Pinyan
      ... If you are *sure* the first character after a _ is going to be a letter, your approach is fine. Otherwise, you ll need to work a little harder. If you
      Message 2 of 5 , Dec 1, 2005
      • 0 Attachment
        On Dec 1, Sreeram B S said:

        > (a) Ask for user to input a long word having '_'
        > (underscore) embedded in it.
        > (b) Now, the program has to capitalise the first
        > letter found after each '_'.
        > (c) The program also has to capitalise the first
        > letter of the word.

        > my @tmp;
        > print ("Input string: ");
        > chomp ( $tmp = <STDIN> );
        > @tmp = split(/_/, $tmp);
        > $_ = "\u$_" foreach (@tmp);
        > $tmp = join('_', @tmp);
        > print ("Modified version = $tmp\n");

        If you are *sure* the first character after a '_' is going to be a letter,
        your approach is fine. Otherwise, you'll need to work a little harder.

        If you want to split, operate, and rejoin, I would suggest using map().

        my $modified =
        join "_",
        map { s/([a-zA-Z])/\u$1/; $_ }
        split /_/, $string, -1;

        That splits $string on _'s (and doesn't remove any empty trailing fields),
        then passes that list to map(). The regex in map() finds the first letter
        in the string and uppercases it -- this is important to understand: I'm
        not just uppercasing the first CHARACTER I find, I'm uppercasing the first
        LETTER I find. The map() block then returns the modified string ($_).
        This list of modified strings is passed to join(), which concatenates them
        with _'s in between. This is the simplified way of writing:

        my @parts = split /_/, $string, -1;
        foreach my $p (@parts) {
        $p =~ s/([a-zA-Z])/\u$1/;
        }
        my $modified = join "_", @parts;

        Being able to understand and use the streamlined version I showed first,
        using map, is key to unlocking some of the real power of Perl.

        Another approach that does not require splitting and rejoining the string
        is this regex:

        $string =~ s/((?:^|_)[^a-zA-Z]*)([a-zA-Z])/$1\u$2/g;

        That regex might look daunting, so I'll add the /x modifier and put some
        comments in:

        $string =~ s{

        ( # capture to $1 {
        (?: ^ | _ ) # either the beginning of the string or an _
        [^a-zA-Z]* # and then zero or more non-letters
        ) # }

        ( # capture to $2 {
        [a-zA-Z] # one letter
        ) # }

        }{$1\u$2}xg; # and replace with $1 followed by uppercased $2

        Ta da. It does what you ask without splitting, processing, and rejoining.
        I'd hazard a guess that the regex is faster, but I haven't benchmarked
        them.

        --
        Jeff "japhy" Pinyan % How can we ever be the sold short or
        RPI Acacia Brother #734 % the cheated, we who for every service
        http://www.perlmonks.org/ % have long ago been overpaid?
        http://princeton.pm.org/ % -- Meister Eckhart
      • Sreeram B S
        ... Hello Jeff, Thanks for the detailed explaination of both the methods. However, I failed to clealy understand the first portion of the regex ie
        Message 3 of 5 , Dec 1, 2005
        • 0 Attachment
          --- Jeff 'japhy' Pinyan <japhy@...> wrote:

          > On Dec 1, Sreeram B S said:
          >
          > > (a) Ask for user to input a long word having '_'
          > > (underscore) embedded in it.
          > > (b) Now, the program has to capitalise the first
          > > letter found after each '_'.
          > > (c) The program also has to capitalise the first
          > > letter of the word.
          >
          > > my @tmp;
          > > print ("Input string: ");
          > > chomp ( $tmp = <STDIN> );
          > > @tmp = split(/_/, $tmp);
          > > $_ = "\u$_" foreach (@tmp);
          > > $tmp = join('_', @tmp);
          > > print ("Modified version = $tmp\n");
          >
          > If you are *sure* the first character after a '_' is
          > going to be a letter,
          > your approach is fine. Otherwise, you'll need to
          > work a little harder.
          >
          > If you want to split, operate, and rejoin, I would
          > suggest using map().
          >
          > my $modified =
          > join "_",
          > map { s/([a-zA-Z])/\u$1/; $_ }
          > split /_/, $string, -1;
          >
          > That splits $string on _'s (and doesn't remove any
          > empty trailing fields),
          > then passes that list to map(). The regex in map()
          > finds the first letter
          > in the string and uppercases it -- this is important
          > to understand: I'm
          > not just uppercasing the first CHARACTER I find, I'm
          > uppercasing the first
          > LETTER I find. The map() block then returns the
          > modified string ($_).
          > This list of modified strings is passed to join(),
          > which concatenates them
          > with _'s in between. This is the simplified way of
          > writing:
          >
          > my @parts = split /_/, $string, -1;
          > foreach my $p (@parts) {
          > $p =~ s/([a-zA-Z])/\u$1/;
          > }
          > my $modified = join "_", @parts;
          >
          > Being able to understand and use the streamlined
          > version I showed first,
          > using map, is key to unlocking some of the real
          > power of Perl.
          >
          > Another approach that does not require splitting and
          > rejoining the string
          > is this regex:
          >
          > $string =~
          > s/((?:^|_)[^a-zA-Z]*)([a-zA-Z])/$1\u$2/g;
          >
          > That regex might look daunting, so I'll add the /x
          > modifier and put some
          > comments in:
          >
          > $string =~ s{
          >
          > ( # capture to $1 {
          > (?: ^ | _ ) # either the beginning of the
          > string or an _
          > [^a-zA-Z]* # and then zero or more
          > non-letters
          > ) # }
          >
          > ( # capture to $2 {
          > [a-zA-Z] # one letter
          > ) # }
          >
          > }{$1\u$2}xg; # and replace with $1 followed
          > by uppercased $2
          >
          > Ta da. It does what you ask without splitting,
          > processing, and rejoining.
          > I'd hazard a guess that the regex is faster, but I
          > haven't benchmarked
          > them.
          >
          > --
          Hello Jeff,
          Thanks for the detailed explaination of both the
          methods. However, I failed to clealy understand the
          first portion of the regex ie ((?:^|_)[^a-zA-Z]*)
          What is the role of (?:^|_) here?

          Kindly let me know about it.

          Thanks,
          Sreeram




          __________________________________________
          Yahoo! DSL – Something to write home about.
          Just $16.99/mo. or less.
          dsl.yahoo.com
        • Mirza Abdullah Jan
          Dear All I need a free graphical software for PERL. Please any body let me know about it . Thank Mirza Abdullah Jan ... Hello Jeff, Thanks for the detailed
          Message 4 of 5 , Dec 2, 2005
          • 0 Attachment
            Dear All
            I need a free graphical software for PERL.
            Please any body let me know about it .

            Thank

            Mirza Abdullah Jan

            Sreeram B S <sreeramabsc@...> wrote:

            --- Jeff 'japhy' Pinyan <japhy@...> wrote:

            > On Dec 1, Sreeram B S said:
            >
            > > (a) Ask for user to input a long word having '_'
            > > (underscore) embedded in it.
            > > (b) Now, the program has to capitalise the first
            > > letter found after each '_'.
            > > (c) The program also has to capitalise the first
            > > letter of the word.
            >
            > > my @tmp;
            > > print ("Input string: ");
            > > chomp ( $tmp = <STDIN> );
            > > @tmp = split(/_/, $tmp);
            > > $_ = "\u$_" foreach (@tmp);
            > > $tmp = join('_', @tmp);
            > > print ("Modified version = $tmp\n");
            >
            > If you are *sure* the first character after a '_' is
            > going to be a letter,
            > your approach is fine. Otherwise, you'll need to
            > work a little harder.
            >
            > If you want to split, operate, and rejoin, I would
            > suggest using map().
            >
            > my $modified =
            > join "_",
            > map { s/([a-zA-Z])/\u$1/; $_ }
            > split /_/, $string, -1;
            >
            > That splits $string on _'s (and doesn't remove any
            > empty trailing fields),
            > then passes that list to map(). The regex in map()
            > finds the first letter
            > in the string and uppercases it -- this is important
            > to understand: I'm
            > not just uppercasing the first CHARACTER I find, I'm
            > uppercasing the first
            > LETTER I find. The map() block then returns the
            > modified string ($_).
            > This list of modified strings is passed to join(),
            > which concatenates them
            > with _'s in between. This is the simplified way of
            > writing:
            >
            > my @parts = split /_/, $string, -1;
            > foreach my $p (@parts) {
            > $p =~ s/([a-zA-Z])/\u$1/;
            > }
            > my $modified = join "_", @parts;
            >
            > Being able to understand and use the streamlined
            > version I showed first,
            > using map, is key to unlocking some of the real
            > power of Perl.
            >
            > Another approach that does not require splitting and
            > rejoining the string
            > is this regex:
            >
            > $string =~
            > s/((?:^|_)[^a-zA-Z]*)([a-zA-Z])/$1\u$2/g;
            >
            > That regex might look daunting, so I'll add the /x
            > modifier and put some
            > comments in:
            >
            > $string =~ s{
            >
            > ( # capture to $1 {
            > (?: ^ | _ ) # either the beginning of the
            > string or an _
            > [^a-zA-Z]* # and then zero or more
            > non-letters
            > ) # }
            >
            > ( # capture to $2 {
            > [a-zA-Z] # one letter
            > ) # }
            >
            > }{$1\u$2}xg; # and replace with $1 followed
            > by uppercased $2
            >
            > Ta da. It does what you ask without splitting,
            > processing, and rejoining.
            > I'd hazard a guess that the regex is faster, but I
            > haven't benchmarked
            > them.
            >
            > --
            Hello Jeff,
            Thanks for the detailed explaination of both the
            methods. However, I failed to clealy understand the
            first portion of the regex ie ((?:^|_)[^a-zA-Z]*)
            What is the role of (?:^|_) here?

            Kindly let me know about it.

            Thanks,
            Sreeram




            __________________________________________
            Yahoo! DSL – Something to write home about.
            Just $16.99/mo. or less.
            dsl.yahoo.com



            Unsubscribing info is here: http://help.yahoo.com/help/us/groups/groups-32.html



            SPONSORED LINKS
            Basic programming language C programming language Computer programming languages The c programming language C programming language List of programming languages

            ---------------------------------
            YAHOO! GROUPS LINKS


            Visit your group "perl-beginner" on the web.

            To unsubscribe from this group, send an email to:
            perl-beginner-unsubscribe@yahoogroups.com

            Your use of Yahoo! Groups is subject to the Yahoo! Terms of Service.


            ---------------------------------






            ---------------------------------
            Yahoo! Personals
            Let fate take it's course directly to your email.
            See who's waiting for you Yahoo! Personals

            [Non-text portions of this message have been removed]
          • Jeff 'japhy' Pinyan
            ... (?:...) is like (...) in that it groups a bunch of regex pieces together as a unit, so you can say /a(?:bc)+/ and it ll match abc , abcbc , abcbcbc ,
            Message 5 of 5 , Dec 2, 2005
            • 0 Attachment
              On Dec 1, Sreeram B S said:

              >> $string =~ s{
              >>
              >> ( # capture to $1 {
              >> (?: ^ | _ ) # either the beginning of the string or an _
              >> [^a-zA-Z]* # and then zero or more non-letters
              >> ) # }
              >>
              >> ( # capture to $2 {
              >> [a-zA-Z] # one letter
              >> ) # }
              >>
              >> }{$1\u$2}xg; # and replace with $1 followed by uppercased $2
              >
              > Thanks for the detailed explaination of both the
              > methods. However, I failed to clealy understand the
              > first portion of the regex ie ((?:^|_)[^a-zA-Z]*)
              > What is the role of (?:^|_) here?

              (?:...) is like (...) in that it groups a bunch of regex pieces together
              as a unit, so you can say /a(?:bc)+/ and it'll match "abc", "abcbc",
              "abcbcbc", etc. The difference between (?:...) and (...) is that (?:...)
              doesn't create a capturing variable ($1, $2, $3, etc.) like (...) does.

              In my regex, (?:^|_) is being used to specify the left-hand boundary of
              the thing we're trying to uppercase. In the string "this_that_those", I
              want to deal with the first letter after each '_', but I ALSO want to deal
              with the very first letter I see, because the string doesn't BEGIN with an
              underscore character. If the string were "_this_that_those", then my
              regex would just be

              s/(_[^a-zA-Z]*)([a-zA-Z])/$1\u$2/g;

              --
              Jeff "japhy" Pinyan % How can we ever be the sold short or
              RPI Acacia Brother #734 % the cheated, we who for every service
              http://www.perlmonks.org/ % have long ago been overpaid?
              http://princeton.pm.org/ % -- Meister Eckhart
            Your message has been successfully submitted and would be delivered to recipients shortly.