FAQ
I'm running PERL under the MACOSX.

The line

$text=~s/george/tim/;

causes a global substituion of "george" with "tim"

How can I limit the substituion to the first instance only?

Thanks!

Search Discussions

  • John W. Krahn at Feb 22, 2012 at 2:43 am

    sb@missionstclare.com wrote:
    I'm running PERL under the MACOSX.
    It is spelled Perl, not PERL. :-)

    The line

    $text=~s/george/tim/;

    causes a global substituion of "george" with "tim"

    How can I limit the substituion to the first instance only?
    Global substitution only works if you use the /g option but your example
    does not use the /g option so it will only replace the first 'george' it
    finds.



    John
    --
    Any intelligent fool can make things bigger and
    more complex... It takes a touch of genius -
    and a lot of courage to move in the opposite
    direction. -- Albert Einstein
  • Timothy adigun at Feb 22, 2012 at 8:02 am
    Hi,
    On Wed, Feb 22, 2012 at 3:43 AM, John W. Krahn wrote:

    sb@missionstclare.com wrote:
    I'm running PERL under the MACOSX.
    It is spelled Perl, not PERL. :-)



    The line
    $text=~s/george/tim/;

    causes a global substituion of "george" with "tim"

    How can I limit the substituion to the first instance only?
    Global substitution only works if you use the /g option but your example
    does not use the /g option so it will only replace the first 'george' it
    finds.

    Correct, but sometimes this doesn't work all of the time, especially
    with some very funny text files.
    So, if John suggestion doesn't work as it should, then you may have to
    enable slurp mode like this:
    $/=undef or local $/;
    So your code could read:

    {
    .....
    $/=undef; ## or use local $/;
    $text=~s/george/tim/;
    ........
    }

    You could check *perldoc perlvar* for more information.
    --
    Tim
  • Jim Gibson at Feb 22, 2012 at 3:45 pm

    At 9:02 AM +0100 2/22/12, timothy adigun wrote:
    On Wed, Feb 22, 2012 at 3:43 AM, John W. Krahn wrote:
    sb@missionstclare.com wrote:

    The line
    $text=~s/george/tim/;

    causes a global substituion of "george" with "tim"
    How can I limit the substituion to the first instance only?
    Global substitution only works if you use the /g option but your example
    does not use the /g option so it will only replace the first 'george' it
    finds.
    Correct, but sometimes this doesn't work all of the time, especially
    with some very funny text files.
    Could you please provide an example of where the given regular
    expression fails to substitute only the first instance of the matched
    pattern?
    So, if John suggestion doesn't work as it should, then you may have to
    enable slurp mode like this:
    $/=undef or local $/;
    So your code could read:

    {
    .....
    $/=undef; ## or use local $/;
    $text=~s/george/tim/;
    ........
    }

    Setting $/ will not affect the results of the substitution. It will
    affect reading a file, but you are not reading a file within the
    scope of the modified $/ variable.

    You can use the File::Slurp module to read a file into a scalar
    variable. Also check out 'perldoc -q entire' "How can I read an
    entire file all at once?"
    You could check *perldoc perlvar* for more information.
    We don't know if the original poster was applying the substitution to
    an entire file or to each line in a file. We don't even know if sb
    was even working with files at all.
  • Uri Guttman at Feb 22, 2012 at 4:39 pm

    On 02/22/2012 03:02 AM, timothy adigun wrote:

    So, if John suggestion doesn't work as it should, then you may have to
    enable slurp mode like this:
    $/=undef or local $/;
    So your code could read:

    {
    .....
    $/=undef; ## or use local $/;
    those are not equivilent. the first is setting $/ to undef and it will
    last past the block, affecting all other <> calls. the local one will
    set it only for the duration of this block but also for any calls made
    inside this block that also may do <> ops. in general neither is a good
    idea. use File::Slurp if you want to read whole files in. it is cleaner
    and also faster than setting $/ to undef.
    $text=~s/george/tim/;
    ........
    }
    uri
  • Timothy adigun at Feb 22, 2012 at 7:56 pm
    Hi,
    On Wed, Feb 22, 2012 at 4:45 PM, Jim Gibson wrote:
    At 9:02 AM +0100 2/22/12, timothy adigun wrote:
    On Wed, Feb 22, 2012 at 3:43 AM, John W. Krahn wrote:
    sb@missionstclare.com wrote:
    The line
    $text=~s/george/tim/;

    causes a global substituion of "george" with "tim"
    How can I limit the substituion to the first instance only?
    Global substitution only works if you use the /g option but your example
    does not use the /g option so it will only replace the first 'george' it
    finds.

    Correct, but sometimes this doesn't work all of the time, especially
    with some very funny text files.
    Could you please provide an example of where the given regular expression
    fails to substitute only the first instance of the matched pattern?


    So, if John suggestion doesn't work as it should, then you may have to
    enable slurp mode like this:
    $/=undef or local $/;
    So your code could read:

    {
    .....
    $/=undef; ## or use local $/;
    $text=~s/george/tim/;
    ........
    }

    Setting $/ will not affect the results of the substitution. It will affect
    reading a file, but you are not reading a file within the scope of the
    modified $/ variable.
    Why Not? If your while(<>){...} is within the scope of { local $/;
    ....}, atleast that is what am suggesting.

    You can use the File::Slurp module to read a file into a scalar variable.
    Also check out 'perldoc -q entire' "How can I read an entire file all at
    once?"

    Please, I don't mean to sound arrogant, but 'perldoc -q entire' "How
    can I read an entire file all at once?" add nothing to me, because all
    brian d foy mentioned is what I think any serious Perl programmer should
    know.
    Agreed File::Slurp will be faster and better as Uri mentioned.
    You could check *perldoc perlvar* for more information.
    We don't know if the original poster was applying the substitution to an
    entire file or to each line in a file. We don't even know if sb was even
    working with files at all.
    True, but atleast we know if the 'original poster' didn't have this
    problem he won't be asking. Will he?
    And if I haven't seen something 'like' that before, I won't be stating it.
    All I did, when **s/college/SCHOOL/;** wouldn't work was:
    {
    local $/;
    while(<>){
    .......
    s/college/SCHOOL/;
    ........
    }
    }
    Bingo! The job was done!

    --
    Tim
  • Sb at Feb 23, 2012 at 12:40 am

    Quoting timothy adigun <2teezperl@gmail.com>:

    Hi,
    On Wed, Feb 22, 2012 at 4:45 PM, Jim Gibson wrote:
    At 9:02 AM +0100 2/22/12, timothy adigun wrote:
    On Wed, Feb 22, 2012 at 3:43 AM, John W. Krahn wrote:
    sb@missionstclare.com wrote:
    The line
    $text=~s/george/tim/;

    causes a global substituion of "george" with "tim"
    How can I limit the substituion to the first instance only?
    Global substitution only works if you use the /g option but your example
    does not use the /g option so it will only replace the first 'george' it
    finds.

    Correct, but sometimes this doesn't work all of the time, especially
    with some very funny text files.
    Could you please provide an example of where the given regular expression
    fails to substitute only the first instance of the matched pattern?


    So, if John suggestion doesn't work as it should, then you may have to
    enable slurp mode like this:
    $/=undef or local $/;
    So your code could read:

    {
    .....
    $/=undef; ## or use local $/;
    $text=~s/george/tim/;
    ........
    }

    Setting $/ will not affect the results of the substitution. It will affect
    reading a file, but you are not reading a file within the scope of the
    modified $/ variable.
    Why Not? If your while(<>){...} is within the scope of { local $/;
    ....}, atleast that is what am suggesting.

    You can use the File::Slurp module to read a file into a scalar variable.
    Also check out 'perldoc -q entire' "How can I read an entire file all at
    once?"

    Please, I don't mean to sound arrogant, but 'perldoc -q entire' "How
    can I read an entire file all at once?" add nothing to me, because all
    brian d foy mentioned is what I think any serious Perl programmer should
    know.
    Agreed File::Slurp will be faster and better as Uri mentioned.
    You could check *perldoc perlvar* for more information.
    We don't know if the original poster was applying the substitution to an
    entire file or to each line in a file. We don't even know if sb was even
    working with files at all.
    True, but atleast we know if the 'original poster' didn't have this
    problem he won't be asking. Will he?
    And if I haven't seen something 'like' that before, I won't be stating it.
    All I did, when **s/college/SCHOOL/;** wouldn't work was:
    {
    local $/;
    while(<>){
    .......
    s/college/SCHOOL/;
    ........
    }
    }
    Bingo! The job was done!

    --
    Tim
    I am changing entire files.

    I maintain missionstclare.com. I can create the daily files from Perl
    scripts (and I do). Example at
    http://www.missionstclare.com/english/March/morning/01m.html

    But, to create the stripped-down versions of the same files (example
    at
    http://www.missionstclare.com/english/March/whole/morning/01m.html), I
    have to remove a great amount of stuff from the original daily files.

    Like Tim, I've been using while(<>); but, from this discussion, I
    suspect that while(<>) is the problem.

    I've never used Slurp.
  • John W. Krahn at Feb 23, 2012 at 1:07 am

    sb@missionstclare.com wrote:
    I am changing entire files.

    I maintain missionstclare.com. I can create the daily files from Perl
    scripts (and I do). Example at
    http://www.missionstclare.com/english/March/morning/01m.html

    But, to create the stripped-down versions of the same files (example at
    http://www.missionstclare.com/english/March/whole/morning/01m.html), I
    have to remove a great amount of stuff from the original daily files.

    Like Tim, I've been using while(<>); but, from this discussion, I
    suspect that while(<>) is the problem.

    I've never used Slurp.
    Now I think I see what the problem is. You are doing something like this:

    while ( my $text = <FH> ) {

    $text =~ s/george/tim/;

    }

    Which substitutes 'tim' for 'george' each time the value in $text
    changes, which is for each line in the file.

    If you only want the first instance of 'george' changed in the whole
    file then you could use the spacial ?? pattern match:

    while ( my $text = <FH> ) {

    $text =~ ?george? && $text =~ s/george/tim/;

    }



    John
    --
    Any intelligent fool can make things bigger and
    more complex... It takes a touch of genius -
    and a lot of courage to move in the opposite
    direction. -- Albert Einstein

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupbeginners @
categoriesperl
postedFeb 22, '12 at 2:37a
activeFeb 23, '12 at 1:07a
posts8
users5
websiteperl.org

People

Translate

site design / logo © 2022 Grokbase