This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
More doc fixes from Abigail.
[perl5.git] / pod / perlfaq6.pod
index 1cec15c..488a27c 100644 (file)
@@ -1,6 +1,6 @@
 =head1 NAME
 
-perlfaq6 - Regexps ($Revision: 1.16 $, $Date: 1997/03/25 18:16:56 $)
+perlfaq6 - Regexps ($Revision: 1.22 $, $Date: 1998/07/16 14:01:07 $)
 
 =head1 DESCRIPTION
 
@@ -25,7 +25,7 @@ comments.
 
     # turn the line into the first word, a colon, and the
     # number of characters on the rest of the line
-    s/^(\w+)(.*)/ lc($1) . ":" . length($2) /ge;
+    s/^(\w+)(.*)/ lc($1) . ":" . length($2) /meg;
 
 =item Comments Inside the Regexp
 
@@ -69,8 +69,9 @@ delimiter within the pattern:
 
 =head2 I'm having trouble matching over more than one line.  What's wrong?
 
-Either you don't have newlines in your string, or you aren't using the
-correct modifier(s) on your pattern.
+Either you don't have more than one line in the string you're looking at
+(probably), or else you aren't using the correct modifier(s) on your
+pattern (possibly).
 
 There are many ways to get multiline data into a string.  If you want
 it to happen automatically while reading input, you'll want to set $/
@@ -94,7 +95,7 @@ record read in.
 
     $/ = '';           # read in more whole paragraph, not just one line
     while ( <> ) {
-       while ( /\b(\w\S+)(\s+\1)+\b/gi ) {
+       while ( /\b([\w'-]+)(\s+\1)+\b/gi ) {   # word starts alpha
            print "Duplicate $1 at paragraph $.\n";
        }
     }
@@ -133,12 +134,23 @@ But if you want nested occurrences of C<START> through C<END>, you'll
 run up against the problem described in the question in this section
 on matching balanced text.
 
+Here's another example of using C<..>:
+
+    while (<>) {
+        $in_header =   1  .. /^$/;
+        $in_body   = /^$/ .. eof();
+       # now choose between them
+    } continue {
+       reset if eof();         # fix $.
+    } 
+
 =head2 I put a regular expression into $/ but it didn't work. What's wrong?
 
 $/ must be a string, not a regular expression.  Awk has to be better
 for something. :-)
 
-Actually, you could do this if you don't mind reading the whole file into
+Actually, you could do this if you don't mind reading the whole file
+into memory:
 
     undef $/;
     @records = split /your_pattern/, <FH>;
@@ -210,7 +222,7 @@ This prints:
 
     this is a SUcCESS case
 
-=head2 How can I make C<\w> match accented characters?
+=head2 How can I make C<\w> match national character sets?
 
 See L<perllocale>.
 
@@ -240,7 +252,7 @@ Without the \Q, the regexp would also spuriously match "di".
 
 =head2 What is C</o> really for?
 
-Using a variable in a regular expression match forces a reevaluation
+Using a variable in a regular expression match forces a re-evaluation
 (and perhaps recompilation) each time through.  The C</o> modifier
 locks in the regexp the first time it's used.  This always happens in a
 constant regular expression, and in fact, the pattern was compiled
@@ -325,9 +337,9 @@ playing hot potato.
 Use the split function:
 
     while (<>) {
-       foreach $word ( split ) {
+       foreach $word ( split ) { 
            # do something with $word here
-       }
+       } 
     }
 
 Note that this isn't really a word in the English sense; it's just
@@ -360,7 +372,7 @@ in the previous question:
 If you wanted to do the same thing for lines, you wouldn't need a
 regular expression:
 
-    while (<>) {
+    while (<>) { 
        $seen{$_}++;
     }
     while ( ($line, $count) = each %seen ) {
@@ -478,15 +490,17 @@ Or, using C<\G>, the much simpler (and faster):
 
 A more sophisticated use might involve a tokenizer.  The following
 lex-like example is courtesy of Jeffrey Friedl.  It did not work in
-5.003 due to bugs in that release, but does work in 5.004 or better:
+5.003 due to bugs in that release, but does work in 5.004 or better.
+(Note the use of C</c>, which prevents a failed match with C</g> from
+resetting the search position back to the beginning of the string.)
 
     while (<>) {
       chomp;
       PARSER: {
-           m/ \G( \d+\b    )/g    && do { print "number: $1\n";  redo; };
-           m/ \G( \w+      )/g    && do { print "word:   $1\n";  redo; };
-           m/ \G( \s+      )/g    && do { print "space:  $1\n";  redo; };
-           m/ \G( [^\w\d]+ )/g    && do { print "other:  $1\n";  redo; };
+           m/ \G( \d+\b    )/gcx    && do { print "number: $1\n";  redo; };
+           m/ \G( \w+      )/gcx    && do { print "word:   $1\n";  redo; };
+           m/ \G( \s+      )/gcx    && do { print "space:  $1\n";  redo; };
+           m/ \G( [^\w\d]+ )/gcx    && do { print "other:  $1\n";  redo; };
       }
     }
 
@@ -495,19 +509,19 @@ Of course, that could have been written as
     while (<>) {
       chomp;
       PARSER: {
-          if ( /\G( \d+\b    )/gx  {
+          if ( /\G( \d+\b    )/gcx  {
                print "number: $1\n";
                redo PARSER;
           }
-          if ( /\G( \w+      )/gx  {
+          if ( /\G( \w+      )/gcx  {
                print "word: $1\n";
                redo PARSER;
           }
-          if ( /\G( \s+      )/gx  {
+          if ( /\G( \s+      )/gcx  {
                print "space: $1\n";
                redo PARSER;
           }
-          if ( /\G( [^\w\d]+ )/gx  {
+          if ( /\G( [^\w\d]+ )/gcx  {
                print "other: $1\n";
                redo PARSER;
           }
@@ -520,7 +534,7 @@ But then you lose the vertical alignment of the regular expressions.
 
 While it's true that Perl's regular expressions resemble the DFAs
 (deterministic finite automata) of the egrep(1) program, they are in
-fact implemented as NFAs (nondeterministic finite automata) to allow
+fact implemented as NFAs (non-deterministic finite automata) to allow
 backtracking and backreferencing.  And they aren't POSIX-style either,
 because those guarantee worst-case behavior for all cases.  (It seems
 that some people prefer guarantees of consistency, even when what's
@@ -531,12 +545,10 @@ L<perlfaq2>).
 
 =head2 What's wrong with using grep or map in a void context?
 
-Strictly speaking, nothing.  Stylistically speaking, it's not a good
-way to write maintainable code.  That's because you're using these
-constructs not for their return values but rather for their
-side-effects, and side-effects can be mystifying.  There's no void
-grep() that's not better written as a C<for> (well, C<foreach>,
-technically) loop.
+Both grep and map build a return list, regardless of their context.
+This means you're making Perl go to the trouble of building up a
+return list that you then just ignore.  That's no way to treat a
+programming language, you insensitive scoundrel!
 
 =head2 How can I match strings with multibyte characters?
 
@@ -546,19 +558,20 @@ synonymous.  The following set of approaches was offered by Jeffrey
 Friedl, whose article in issue #5 of The Perl Journal talks about this
 very matter.
 
-Let's suppose you have some weird Martian encoding where pairs of ASCII
-uppercase letters encode single Martian letters (i.e. the two bytes
-"CV" make a single Martian letter, as do the two bytes "SG", "VS",
-"XX", etc.). Other bytes represent single characters, just like ASCII.
+Let's suppose you have some weird Martian encoding where pairs of
+ASCII uppercase letters encode single Martian letters (i.e. the two
+bytes "CV" make a single Martian letter, as do the two bytes "SG",
+"VS", "XX", etc.). Other bytes represent single characters, just like
+ASCII.
 
-So, the string of Martian "I am CVSGXX!" uses 12 bytes to encode the nine
-characters 'I', ' ', 'a', 'm', ' ', 'CV', 'SG', 'XX', '!'.
+So, the string of Martian "I am CVSGXX!" uses 12 bytes to encode the
+nine characters 'I', ' ', 'a', 'm', ' ', 'CV', 'SG', 'XX', '!'.
 
 Now, say you want to search for the single character C</GX/>. Perl
-doesn't know about Martian, so it'll find the two bytes "GX" in the
-"I am CVSGXX!"  string, even though that character isn't there: it just
-looks like it is because "SG" is next to "XX", but there's no real "GX".
-This is a big problem.
+doesn't know about Martian, so it'll find the two bytes "GX" in the "I
+am CVSGXX!"  string, even though that character isn't there: it just
+looks like it is because "SG" is next to "XX", but there's no real
+"GX".  This is a big problem.
 
 Here are a few ways, all painful, to deal with it:
 
@@ -590,11 +603,24 @@ katakana (in Shift-JIS or EUC encoding) is available from CPAN as
 
 =for Tom make it so
 
-There are many double (and multi) byte encodings commonly used these
+There are many double- (and multi-) byte encodings commonly used these
 days.  Some versions of these have 1-, 2-, 3-, and 4-byte characters,
 all mixed.
 
 =head1 AUTHOR AND COPYRIGHT
 
-Copyright (c) 1997 Tom Christiansen and Nathan Torkington.
-All rights reserved.  See L<perlfaq> for distribution information.
+Copyright (c) 1997, 1998 Tom Christiansen and Nathan Torkington.
+All rights reserved.
+
+When included as part of the Standard Version of Perl, or as part of
+its complete documentation whether printed or otherwise, this work
+may be distributed only under the terms of Perl's Artistic License.
+Any distribution of this file or derivatives thereof I<outside>
+of that package require that special arrangements be made with
+copyright holder.
+
+Irrespective of its distribution, all code examples in this file
+are hereby placed into the public domain.  You are permitted and
+encouraged to use this code in your own programs for fun
+or for profit as you see fit.  A simple comment in the code giving
+credit would be courteous but is not required.