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

In my perl program, when I read in a line of text, how can I perform the action of substituting all the words before a certain in the middle of a line. For example: READIN LINE: This is a nice weather. He is a nice guy. We have some nice food in our dinner. Substituting everything before " nice" with "A" (though the phrase in front are all different), i.e. EXPECTING RESULT: A nice weather. A nice guy. A nice food in our dinner. How can I do this is perl?
  • Comment on How to substitute all the words before a certain word in the middle of a line?

Replies are listed 'Best First'.
(chromatic) Re: How to substitute all the words before a certain word in the middle of a line?
by chromatic (Archbishop) on Jul 12, 2000 at 09:30 UTC
    Here's a happy little regex:
    my $sentence = "This is a nice weather. He is a nice guy. We have some nice food in our dinner."; $sentence =~ s:(\w+\s)+(\bnice\b.*?\.):A $2:g; print "$sentence\n";
    That looks for a word followed by a space, repeated any number of times, followed by the word nice (with word boundaries around it) followed by a minimal number of characters before a final period. It replaces the first bit with 'A' and keeps the second around. /g, of course, makes it look for all the matches in the string.
Re: How to substitute all the words before a certain word in the middle of a line?
by Anonymous Monk on Jul 12, 2000 at 17:31 UTC

    The first one almost does the job, but it's simpler just to discard every single character before the nice IMHO...

    my $sentence = "This is a nice weather. He is a nice guy.
    We have some nice food in our dinner.";
    $sentence =~ s:.*(\bnice\b.*?\.):A $1:g;
    print "$sentence\n";

RE: How to substitute all the words before a certain word in the middle of a line?
by Ovid (Cardinal) on Jul 12, 2000 at 21:20 UTC
    Better late than never: here's my take on the situation.
    $test = "This is a nice weather. He is a nice guy. We have some nice f +ood in our dinner."; $test =~ s/(?:.*?)(\bnice\b[^.]*\.\s*)/A $1/g; print $test;
    The (?: allows grouping without backreferencing, thus making the regex a little more efficient. The [^.] after the word "nice" forces it to match up to, but excluding the period. This is much more efficient than the dot star ".*" because of the way Perl's regex engine works. Unfortunately, I could not figure out a clean way of getting rid of the first dot star.

    Cheers,
    Ovid

Re: How to substitute all the words before a certain word in the middle of a line?
by vkonovalov (Monk) on Jul 12, 2000 at 09:36 UTC
    s/\b\w+\s+nice\b/A nice/g;
    or
    $w = 'nice'; $r = 'A'; s/\b\w+(\s+$w)\b/$r$1/g;
    should work
      The first one does not work, at least not here, when I supply the given sentence.
      You just replace the last word before 'nice' with 'A'.
        More careful reading will help in my case :)
        The word "all" was lost by me :)
RE: How to substitute all the words before a certain word in the middle of a line?
by Emphyrio (Beadle) on Jul 12, 2000 at 13:42 UTC
    This would be a solution, keeping in mind that we assume all '.' characters terminate a line.

    $line="This is a nice weather. He is a nice guy. We have some nice food in our dinner.";

    foreach (split /\./,$line) {
    s/^.*(nice.*)/$1/;
    $result.="A $_.";
    }
    print $result;

      I doubt that this code will work properly... I think this algorithm is far away of originally desired one.
Re: How to substitute all the words before a certain word in the middle of a line?
by Ted Nitz (Chaplain) on Jul 12, 2000 at 20:01 UTC
    I'm assuming that there should have been line breaks in the sample data, so that each sentince was on a separate line. Also, this code will match everything before the first occurance of the trigger word (nice in this case). You can replace <DATA> with another filehandle or with <> depending upon where you want to get the lines.
    my $triggerword = "nice"; my $replacement = "A "; while(<DATA>){ s/^.*?(?=$triggerword)/$replacement/o; print; } __DATA__ This is a nice weather. He is a nice guy. We have some nice food in our dinner.
Re: How to substitute all the words before a certain word in the middle of a line?
by ZZamboni (Curate) on Jul 12, 2000 at 22:54 UTC
    Just because TIMTOWTDI, here's another way. If you know that all your sentences are separated by periods:
    foreach (@x=split(/(\.\s+)/, $text)) { s/^.*(\bnice\b.*)$/A $1/; } $text=join("", @x);
    Don't go with it, though. chromatic's regex is much nicer :-)

    --ZZamboni