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

I don't quite know where on PerlMonks this belongs, but I'll put it here and let the admins decide.

I read Japhy's draft chapters of his book on regular expressions and wrote to him with some suggestions, (as he invited readers to do) for examples of the /s and /m modifiers and what they do.

I thought I'd post them here as well, in case other monks wanted to comment or add to them:

$" = "\n"; # so the array printouts have linebreaks between elements $string = 'start at the beginning and go on to till the end'; if( $string =~ /^start.*end$/ ){ print 'true' } else { print 'false'} print "\n\n"; # True, obviously, because the string starts with # the character sequence 'start' and ends with 'end' $string = 'start at the beginning and go on till the end'; if( $string =~ /^start.*end$/ ){ print 'true' } else { print 'false'} print "\n\n"; # False, because now there's a newline in the middle. # It still starts with 'start' and ends with 'end', but # the dot-star part in the middle doesn't match the # newline in the middle. If you want to find this # kind of match, add the /s modifier. if( $string =~ /^start.*end$/s ){ print 'true' } else { print 'false'} print "\n\n"; # Now it's true. Dot is allowed to match newlines with /s modifier. # Make the string into a force-wrapped paragraph of text # which matches the pattern as a whole string, but also # contains *lines* which match the pattern and try to # put them all into an array, using the /g modifier. $string = 'start at the beginning, tell the story of how you started a company with your friend and how it collapsed, part of the startup-company-collapse trend of the nineties, and go on till the end'; if( @matches = $string =~ /^start.*end$/g ){ print "Matches: @matches" } else { print 'no matches' } print "\n\n"; # No matches. Not even one, but they should be expecting that, # because, no /s modifier. # What happens if you add the /s modifier? How many matches? if( @matches = $string =~ /^start.*end$/gs ){ print "Matches with s modifier:\n@matches" } else { print 'no matches' } print "\n\n"; # @matches has one item, the entire string. # The *entire string* matches because the entire string # has only one start point (found by the ^ marker) and only one # end point (found by the $ marker) and dot matches newlines. # If you want the ^ marker and the $ marker to look at the # start point and end point of *lines*, not at the start point # and end point of the *string*, then you need the /m modifier. if( @matches = $string =~ /^start.*end$/gm ){ print "Matches with m modifier:\n@matches" } else { print 'no matches' } print "\n\n"; # Add the /s to it and it again matches the whole string: if( @matches = $string =~ /^start.*end$/gsm ){ print "Matches with m modifier:\n@matches" } else { print 'no matches' } print "\n\n"; # So what would be the point of ever having them # together? It doesn't make sense here, but # it does if you make dot-star non-greedy: if( @matches = $string =~ /^start.*?end$/gsm ){ print "Matches with m modifier:\n@matches" } else { print 'no matches' } print "\n\n"; # This version finds *two* matches, one from the very start # down to the word "friend", then another one, the single line # "startup-company-collapse trend", because the question mark # made the regex find the nearest "end" not the farthest each # time.

--
“Every bit of code is either naturally related to the problem at hand, or else it's an accidental side effect of the fact that you happened to solve the problem using a digital computer.”
M-J D

Replies are listed 'Best First'.
Re: S And M -- modifiers, that is...
by davorg (Chancellor) on Feb 25, 2003 at 11:05 UTC

    The way I remember what /s and /m do is like this. I know that they change the behaviour of regex metacharacters, but /s changes the behaviour of a single metacharacter (.) and /m changes the behaviour of multiple metacharacters (^ and $).

    Don't know whether that will help anyone else.

    --
    <http://www.dave.org.uk>

    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

      I think that's a useful mnemonic. And it may help people to remember that those are the only things the /m and /s modifiers affect. The /s modifier only affects whether "." will match a newline. The /m modifier only affects whether ^ and $ can match at embedded newlines in the middle of a string. Other than that, everything else remains unaffected... in particular, "\n" and "\s" will always match newline characters, regardless of what modifiers are set.

      -- Mike

      --
      just,my${.02}

        don't understand. I actually printed out the size of @matches using "$#matches" and it all came out as 0. So how does the last non-greedy match work? thanks for explaining first.
      That's a useful one. It's actually in the book already, credited to an Andy Wardley.
      --
      “Every bit of code is either naturally related to the problem at hand, or else it's an accidental side effect of the fact that you happened to solve the problem using a digital computer.”
      M-J D
Re: S And M -- modifiers, that is...
by Anonymous Monk on Feb 25, 2003 at 08:00 UTC
    I don't get it, where is this supposed to go? (what chapter)

    I also don't see how it adds anything to the book (it's just a more long-winded explanation of what the book already clearly explains)

      Well, if you've read the book and got to the section on /m and /s, it would go at the bit clearly marked:

      5.1.4 Example: ??? Need an example of /m and /s here. Open to suggestions.

      --
      “Every bit of code is either naturally related to the problem at hand, or else it's an accidental side effect of the fact that you happened to solve the problem using a digital computer.”
      M-J D