This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Rename perlunintro to perluniintro; regen toc.
[perl5.git] / pod / perlfaq6.pod
index 4ab4d4c..be7e8ec 100644 (file)
@@ -1,6 +1,6 @@
 =head1 NAME
 
-perlfaq6 - Regexes ($Revision: 1.27 $, $Date: 1999/05/23 16:08:30 $)
+perlfaq6 - Regexes ($Revision: 1.4 $, $Date: 2001/11/09 08:06:04 $)
 
 =head1 DESCRIPTION
 
@@ -8,8 +8,9 @@ This section is surprisingly small because the rest of the FAQ is
 littered with answers involving regular expressions.  For example,
 decoding a URL and checking whether something is a number are handled
 with regular expressions, but those answers are found elsewhere in
-this document (in the section on Data and the Networking one on
-networking, to be precise).
+this document (in L<perlfaq9>: ``How do I decode or create those %-encodings 
+on the web'' and L<perfaq4>: ``How do I determine whether a scalar is
+a number/whole/integer/float'', to be precise).
 
 =head2 How can I hope to use regular expressions without creating illegible and unmaintainable code?
 
@@ -114,7 +115,7 @@ Here's code that finds everything between START and END in a paragraph:
 
     undef $/;                  # read in whole file, not just one line or paragraph
     while ( <> ) {
-       while ( /START(.*?)END/sm ) { # /s makes . cross line boundaries
+       while ( /START(.*?)END/sgm ) { # /s makes . cross line boundaries
            print "$1\n";
        }
     }
@@ -175,7 +176,7 @@ appear within a certain time.
     $file->waitfor('/second line\n/');
     print $file->getline;
 
-=head2 How do I substitute case insensitively on the LHS, but preserving case on the RHS?
+=head2 How do I substitute case insensitively on the LHS while preserving case on the RHS?
 
 Here's a lovely Perlish solution by Larry Rosler.  It exploits
 properties of bitwise xor on ASCII strings.
@@ -185,7 +186,7 @@ properties of bitwise xor on ASCII strings.
     $old = 'test';
     $new = 'success';
 
-    s{(\Q$old\E}
+    s{(\Q$old\E)}
      { uc $new | (uc $1 ^ $1) .
        (uc(substr $1, -1) ^ substr $1, -1) x
            (length($new) - length $1)
@@ -193,7 +194,7 @@ properties of bitwise xor on ASCII strings.
 
     print;
 
-And here it is as a subroutine, modelled after the above:
+And here it is as a subroutine, modeled after the above:
 
     sub preserve_case($$) {
        my ($old, $new) = @_;
@@ -211,6 +212,21 @@ This prints:
 
     this is a SUcCESS case
 
+As an alternative, to keep the case of the replacement word if it is
+longer than the original, you can use this code, by Jeff Pinyan:
+
+  sub preserve_case {
+    my ($from, $to) = @_;
+    my ($lf, $lt) = map length, @_;
+    
+    if ($lt < $lf) { $from = substr $from, 0, $lt }
+    else { $from .= substr $to, $lf }
+    
+    return uc $to | ($from ^ uc $from);
+  }
+
+This changes the sentence to "this is a SUcCess case."
+
 Just to show that C programmers can write C in any programming language,
 if you prefer a more C-like solution, the following script makes the
 substitution have the same case, letter by letter, as the original.
@@ -280,10 +296,11 @@ Without the \Q, the regex would also spuriously match "di".
 =head2 What is C</o> really for?
 
 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 regex the first time it's used.  This always happens in a
-constant regular expression, and in fact, the pattern was compiled
-into the internal format at the same time your entire program was.
+(and perhaps recompilation) each time the regular expression is
+encountered.  The C</o> modifier locks in the regex the first time
+it's used.  This always happens in a constant regular expression, and
+in fact, the pattern was compiled into the internal format at the same
+time your entire program was.
 
 Use of C</o> is irrelevant unless variable interpolation is used in
 the pattern, and if so, the regex engine will neither know nor care
@@ -366,20 +383,30 @@ A slight modification also removes C++ comments:
 
 =head2 Can I use Perl regular expressions to match balanced text?
 
-Although Perl regular expressions are more powerful than "mathematical"
-regular expressions, because they feature conveniences like backreferences
-(C<\1> and its ilk), they still aren't powerful enough -- with
-the possible exception of bizarre and experimental features in the
-development-track releases of Perl.  You still need to use non-regex
-techniques to parse balanced text, such as the text enclosed between
-matching parentheses or braces, for example.
+Historically, Perl regular expressions were not capable of matching
+balanced text.  As of more recent versions of perl including 5.6.1
+experimental features have been added that make it possible to do this.
+Look at the documentation for the (??{ }) construct in recent perlre manual
+pages to see an example of matching balanced parentheses.  Be sure to take
+special notice of the  warnings present in the manual before making use
+of this feature.
+
+CPAN contains many modules that can be useful for matching text
+depending on the context.  Damian Conway provides some useful
+patterns in Regexp::Common.  The module Text::Balanced provides a
+general solution to this problem.
+
+One of the common applications of balanced text matching is working
+with XML and HTML.  There are many modules available that support
+these needs.  Two examples are HTML::Parser and XML::Parser. There
+are many others.
 
 An elaborate subroutine (for 7-bit ASCII only) to pull out balanced
 and possibly nested single chars, like C<`> and C<'>, C<{> and C<}>,
 or C<(> and C<)> can be found in
-http://www.perl.com/CPAN/authors/id/TOMC/scripts/pull_quotes.gz .
+http://www.cpan.org/authors/id/TOMC/scripts/pull_quotes.gz .
 
-The C::Scan module from CPAN contains such subs for internal usage,
+The C::Scan module from CPAN also contains such subs for internal use,
 but they are undocumented.
 
 =head2 What does it mean that regexes are greedy?  How can I get around it?
@@ -402,7 +429,7 @@ expression engine to find a match as quickly as possible and pass
 control on to whatever is next in line, like you would if you were
 playing hot potato.
 
-=head2  How do I process each word on each line?
+=head2 How do I process each word on each line?
 
 Use the split function:
 
@@ -450,7 +477,8 @@ regular expression:
        print "$count $line";
     }
 
-If you want these output in a sorted order, see the section on Hashes.
+If you want these output in a sorted order, see L<perlfaq4>: ``How do I
+sort a hash (optionally by value instead of key)?''.
 
 =head2 How can I do approximate matching?
 
@@ -487,7 +515,7 @@ approach, one which makes use of the new C<qr//> operator:
 
 =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
+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
@@ -514,11 +542,11 @@ not "this" or "island".
 
 =head2 Why does using $&, $`, or $' slow my program down?
 
-Because once Perl sees that you need one of these variables anywhere in
-the program, it has to provide them on each and every pattern match.
+Once Perl sees that you need one of these variables anywhere in
+the program, it provides them on each and every pattern match.
 The same mechanism that handles these provides for the use of $1, $2,
 etc., so you pay the same price for each regex that contains capturing
-parentheses. But if you never use $&, etc., in your script, then regexes
+parentheses.  If you never use $&, etc., in your script, then regexes
 I<without> capturing parentheses won't be penalized. So avoid $&, $',
 and $` if you can, but if you can't, once you've used them at all, use
 them at will because you've already paid the price.  Remember that some
@@ -589,7 +617,7 @@ Of course, that could have been written as
       }
     }
 
-But then you lose the vertical alignment of the regular expressions.
+but then you lose the vertical alignment of the regular expressions.
 
 =head2 Are Perl regexes DFAs or NFAs?  Are they POSIX compliant?
 
@@ -670,12 +698,12 @@ Well, if it's really a pattern, then just use
     chomp($pattern = <STDIN>);
     if ($line =~ /$pattern/) { }
 
-Or, since you have no guarantee that your user entered
+Alternatively, since you have no guarantee that your user entered
 a valid regular expression, trap the exception this way:
 
     if (eval { $line =~ /$pattern/ }) { }
 
-But if all you really want to search for a string, not a pattern,
+If all you really want to search for a string, not a pattern,
 then you should either use the index() function, which is made for
 string searching, or if you can't be disabused of using a pattern
 match on a non-pattern, then be sure to use C<\Q>...C<\E>, documented
@@ -694,12 +722,8 @@ in L<perlre>.
 Copyright (c) 1997-1999 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.
+This documentation is free; you can redistribute it and/or modify it
+under the same terms as Perl itself.
 
 Irrespective of its distribution, all code examples in this file
 are hereby placed into the public domain.  You are permitted and