cvs commit: perlfaq perlfaq6.pod

[email protected] 14 Feb 2005 18:25:48 -0000
Newsgroups perl.cvs.perlfaq
Message-ID <[email protected]>
cvsuser     05/02/14 10:25:48

  Modified:    .        perlfaq6.pod
  Log:
  * Why don't word-boundary searches with C<\b> work for me?
  
  	* I completely rewrote this answer, so I'm not giving you a
  	diff. It's easier just to read it straight.  As of today and
  	until I commit a change, the current answer is
  	http://faq.perl.org/perlfaq6.html#Why_don_t_word_bound
  
  	* I discovered a slight error in perlre:  it defines \b in
  	terms of \w and \W, but that isn't strictly true since the
  	start and end of strings can stand in for non-word
  	characters.  perlre needs a slight patch before I can
  	reference it.
  
  	* In the old answer, the examples weren't very interesting
  	or concrete, so I added more examples and show several
  	strings that match or don't match a pattern.
  
  Revision  Changes    Path
  1.30      +55 -25    perlfaq/perlfaq6.pod
  
  Index: perlfaq6.pod
  ===================================================================
  RCS file: /cvs/public/perlfaq/perlfaq6.pod,v
  retrieving revision 1.29
  retrieving revision 1.30
  diff -u -r1.29 -r1.30
  --- perlfaq6.pod	31 Jan 2005 15:45:36 -0000	1.29
  +++ perlfaq6.pod	14 Feb 2005 18:25:48 -0000	1.30
  @@ -1,6 +1,6 @@
   =head1 NAME
   
  -perlfaq6 - Regular Expressions ($Revision: 1.29 $, $Date: 2005/01/31 15:45:36 $)
  +perlfaq6 - Regular Expressions ($Revision: 1.30 $, $Date: 2005/02/14 18:25:48 $)
   
   =head1 DESCRIPTION
   
  @@ -573,30 +573,60 @@
   
   =head2 Why don't word-boundary searches with C<\b> work for me?
   
  -Two common misconceptions are that C<\b> is a synonym for C<\s+> and
  -that it's the edge between whitespace characters and non-whitespace
  -characters.  Neither is correct.  C<\b> is the place between a C<\w>
  -character and a C<\W> character (that is, C<\b> is the edge of a
  -"word").  It's a zero-width assertion, just like C<^>, C<$>, and all
  -the other anchors, so it doesn't consume any characters.  L<perlre>
  -describes the behavior of all the regex metacharacters.
  -
  -Here are examples of the incorrect application of C<\b>, with fixes:
  -
  -    "two words" =~ /(\w+)\b(\w+)/;	    # WRONG
  -    "two words" =~ /(\w+)\s+(\w+)/;	    # right
  -
  -    " =matchless= text" =~ /\b=(\w+)=\b/;   # WRONG
  -    " =matchless= text" =~ /=(\w+)=/;       # right
  -
  -Although they may not do what you thought they did, C<\b> and C<\B>
  -can still be quite useful.  For an example of the correct use of
  -C<\b>, see the example of matching duplicate words over multiple
  -lines.
  -
  -An example of using C<\B> is the pattern C<\Bis\B>.  This will find
  -occurrences of "is" on the insides of words only, as in "thistle", but
  -not "this" or "island".
  +(contributed by brian d foy)
  +
  +Ensure that you know what \b really does: it's the boundary between a
  +word character, \w, and something that isn't a word character. That
  +thing that isn't a word character might be \W, but it can also be the
  +start or end of the string.
  +
  +It's not (not!) the boundary between whitespace and non-whitespace,
  +and it's not the stuff between words we use to create sentences.
  +
  +In regex speak, a word boundary (\b) is a "zero width assertion",
  +meaning that it doesn't represent a character in the string, but a
  +condition at a certain position.
  +
  +For the regular expression, /\bPerl\b/, there has to be a word
  +boundary before the "P" and after the "l".  As long as something other
  +than a word character precedes the "P" and succeeds the "l", the
  +pattern will match. These strings match /\bPerl\b/.
  +
  +	"Perl"    # no word char before P or after l
  +	"Perl "   # same as previous (space is not a word char)
  +	"'Perl'"  # the ' char is not a word char
  +	"Perl's"  # no word char before P, non-word char after "l"
  +
  +These strings do not match /\bPerl\b/.
  +
  +	"Perl_"   # _ is a word char!
  +	"Perler"  # no word char before P, but one after l
  +	
  +You don't have to use \b to match words though.  You can look for
  +non-word characters surrrounded by word characters.  These strings
  +match the pattern /\b'\b/.
  +
  +	"don't"   # the ' char is surrounded by "n" and "t"
  +	"qep'a'"  # the ' char is surrounded by "p" and "a"
  +	
  +These strings do not match /\b'\b/.
  +
  +	"foo'"    # there is no word char after non-word '
  +	
  +You can also use the complement of \b, \B, to specify that there
  +should not be a word boundary.
  +
  +In the pattern /\Bam\B/, there must be a word character before the "a"
  +and after the "m". These patterns match /\Bam\B/:
  +
  +	"llama"   # "am" surrounded by word chars
  +	"Samuel"  # same
  +	
  +These strings do not match /\Bam\B/
  +
  +	"Sam"      # no word boundary before "a", but one after "m"
  +	"I am Sam" # "am" surrounded by non-word chars
  +
   
   =head2 Why does using $&, $`, or $' slow my program down?