[svn:perlfaq] r6019 - perlfaq/trunk

[email protected] Thu, 4 May 2006 10:04:32 -0700 (PDT)
Newsgroups perl.cvs.perlfaq
Message-ID <[email protected]>
Author: comdog
Date: Thu May  4 10:04:31 2006
New Revision: 6019

Modified:
   perlfaq/trunk/perlfaq.pod
   perlfaq/trunk/perlfaq1.pod
   perlfaq/trunk/perlfaq3.pod
   perlfaq/trunk/perlfaq4.pod
   perlfaq/trunk/perlfaq5.pod
   perlfaq/trunk/perlfaq6.pod
   perlfaq/trunk/perlfaq8.pod

Log:
* perlfaq6: =head2 How do I efficiently match many regular expressions at once?
	+ fixed a logic bug in the first code example. The foreach() only ever
	looked at the first pattern because of the next();
	+ many whitespace fixes

* Everything else: minor whitespace fixes


Modified: perlfaq/trunk/perlfaq.pod
==============================================================================
--- perlfaq/trunk/perlfaq.pod	(original)
+++ perlfaq/trunk/perlfaq.pod	Thu May  4 10:04:31 2006
@@ -32,7 +32,7 @@
 
 =head2 How to contribute to the perlfaq
 
-You can mail corrections, additions, and suggestions to 
+You can mail corrections, additions, and suggestions to
 C<< <perlfaq-workers AT perl DOT org> >>. The perlfaq volunteers use this
 address to coordinate their efforts and track the perlfaq development.
 They appreciate your contributions to the FAQ but do not have time to
@@ -735,7 +735,7 @@
 
 =item *
 
-How can I make a filehandle local to a subroutine?  How do I pass filehandles between subroutines?  How do I make an array of filehandles? 
+How can I make a filehandle local to a subroutine?  How do I pass filehandles between subroutines?  How do I make an array of filehandles?
 
 =item *
 

Modified: perlfaq/trunk/perlfaq1.pod
==============================================================================
--- perlfaq/trunk/perlfaq1.pod	(original)
+++ perlfaq/trunk/perlfaq1.pod	Thu May  4 10:04:31 2006
@@ -60,7 +60,7 @@
 
 There is often a matter of opinion and taste, and there isn't any one
 answer that fits anyone.  In general, you want to use either the current
-stable release, or the stable release immediately prior to that one. 
+stable release, or the stable release immediately prior to that one.
 Currently, those are perl5.8.x and perl5.6.x, respectively.
 
 Beyond that, you have to consider several things and decide which is best
@@ -373,7 +373,7 @@
 the people using that language. If you or your team can be more faster,
 better, and stronger through Perl, you'll deliver more value. Remember,
 people often respond better to what they get out of it. If you run
-into resistance, figure out what those people get out of the other 
+into resistance, figure out what those people get out of the other
 choice and how Perl might satisfy that requirement.
 
 You don't have to worry about finding or paying for Perl; it's freely

Modified: perlfaq/trunk/perlfaq3.pod
==============================================================================
--- perlfaq/trunk/perlfaq3.pod	(original)
+++ perlfaq/trunk/perlfaq3.pod	Thu May  4 10:04:31 2006
@@ -114,14 +114,14 @@
 
 Before you do anything else, you can help yourself by ensuring that
 you let Perl tell you about problem areas in your code. By turning
-on warnings and strictures, you can head off many problems before 
+on warnings and strictures, you can head off many problems before
 they get too big. You can find out more about these in L<strict>
 and L<warnings>.
 
 	#!/usr/bin/perl
 	use strict;
 	use warnings;
-	
+
 Beyond that, the simplest debugger is the C<print> function. Use it
 to look at values as you run your program:
 
@@ -131,7 +131,7 @@
 
 	use Data::Dumper( Dump );
 	print STDERR "The hash is " . Dump( \%hash ) . "\n";
-	
+
 Perl comes with an interactive debugger, which you can start with the
 C<-d> switch. It's fully explained in L<perldebug>.
 

Modified: perlfaq/trunk/perlfaq4.pod
==============================================================================
--- perlfaq/trunk/perlfaq4.pod	(original)
+++ perlfaq/trunk/perlfaq4.pod	Thu May  4 10:04:31 2006
@@ -117,7 +117,7 @@
 
 Don't blame Perl.  It's the same as in C.  IEEE says we have to do
 this. Perl numbers whose absolute values are integers under 2**31 (on
-32 bit machines) will work pretty much like mathematical integers. 
+32 bit machines) will work pretty much like mathematical integers.
 Other numbers are not guaranteed.
 
 =head2 How do I convert between numeric representations/bases/radixes?
@@ -659,7 +659,7 @@
 	# $_ contains the string to parse
 	# BEGIN and END are the opening and closing markers for the
 	# nested text.
-	
+
 	@( = ('(','');
 	@) = (')','');
 	($re=$_)=~s/((BEGIN)|(END)|.)/$)[!$3]\Q$1\E$([!$2]/gs;
@@ -931,15 +931,15 @@
 	# Left padding a string with blanks (no truncation):
 	$padded = sprintf("%${pad_len}s", $text);
 	$padded = sprintf("%*s", $pad_len, $text);  # same thing
-	
+
 	# Right padding a string with blanks (no truncation):
 	$padded = sprintf("%-${pad_len}s", $text);
 	$padded = sprintf("%-*s", $pad_len, $text); # same thing
-	
+
 	# Left padding a number with 0 (no truncation):
 	$padded = sprintf("%0${pad_len}d", $num);
 	$padded = sprintf("%0*d", $pad_len, $num); # same thing
-	
+
 	# Right padding a string with blanks using pack (will truncate):
 	$padded = pack("A$pad_len",$text);
 
@@ -1192,7 +1192,7 @@
 	my %hash   = map { $_, 1 } @array;
 	# or a hash slice: @hash{ @array } = ();
 	# or a foreach: $hash{$_} = 1 foreach ( @array );
-	
+
 	my @unique = keys %hash;
 
 If you want to use a module, try the C<uniq> function from
@@ -1201,7 +1201,7 @@
 number of unique elements.
 
 	use List::MoreUtils qw(uniq);
-	
+
 	my @unique = uniq( 1, 2, 3, 4, 4, 5, 6, 5, 7 ); # 1,2,3,4,5,6,7
 	my $unique = uniq( 1, 2, 3, 4, 4, 5, 6, 5, 7 ); # 7
 
@@ -1321,7 +1321,7 @@
 undefined empty strings.  Modify if you have other needs.
 
 	$are_equal = compare_arrays(\@frogs, \@toads);
-	
+
 	sub compare_arrays {
 		my ($first, $second) = @_;
 		no warnings;  # silence spurious -w undef complaints
@@ -1347,14 +1347,14 @@
 two different answers:
 
 	use FreezeThaw qw(cmpStr cmpStrHard);
-	
+
 	%a = %b = ( "this" => "that", "extra" => [ "more", "stuff" ] );
 	$a{EXTRA} = \%b;
 	$b{EXTRA} = \%a;
-	
+
 	printf "a and b contain %s hashes\n",
 	cmpStr(\%a, \%b) == 0 ? "the same" : "different";
-	
+
 	printf "a and b contain %s hashes\n",
 	cmpStrHard(\%a, \%b) == 0 ? "the same" : "different";
 
@@ -1429,14 +1429,14 @@
 	for $value ( 2 .. 10 ) {
 		$tail = append($tail, $value);
 		}
-	
+
 	sub append {
 		my($list, $value) = @_;
 		my $node = { VALUE => $value };
 		if ($list) {
 			$node->{LINK} = $list->{LINK};
 			$list->{LINK} = $node;
-			} 
+			}
 		else {
 			$_[0] = $node;      # replace caller's version
 			}
@@ -1456,12 +1456,12 @@
 You can also use C<Tie::Cycle>:
 
 	use Tie::Cycle;
-	
+
 	tie my $cycle, 'Tie::Cycle', [ qw( FFFFFF 000000 FFFF00 ) ];
-	
+
 	print $cycle; # FFFFFF
 	print $cycle; # 000000
-	print $cycle; # FFFF00                                           
+	print $cycle; # FFFF00
 
 =head2 How do I shuffle an array randomly?
 
@@ -1504,7 +1504,7 @@
 		}
 
 This is bad because splice is already O(N), and since you do it N
-times, you just invented a quadratic algorithm; that is, O(N**2). 
+times, you just invented a quadratic algorithm; that is, O(N**2).
 This does not scale, although Perl is so efficient that you probably
 won't notice this until you have rather largish arrays.
 
@@ -1632,7 +1632,7 @@
 
 If you need to sort on several fields, the following paradigm is useful.
 
-	@sorted = sort { 
+	@sorted = sort {
 		field1($a) <=> field1($b) ||
 		field2($a) cmp field2($b) ||
 		field3($a) cmp field3($b)
@@ -1681,7 +1681,7 @@
 				push @ints, $i if vec($vec, ++$i, 1);
 				push @ints, $i if vec($vec, ++$i, 1);
 				}
-			} 
+			}
 		else {
 			# This method is a fast general algorithm
 			use integer;
@@ -1689,7 +1689,7 @@
 			push @ints, 0 if $bits =~ s/^(\d)// && $1;
 			push @ints, pos $bits while($bits =~ /1/g);
 			}
-	
+
 		return \@ints;
 		}
 
@@ -1721,18 +1721,18 @@
 	$is_set = vec($vector, 23, 1);
 	print "Its 23rd bit is ", $is_set ? "set" : "clear", ".\n";
 	pvec($vector);
-	
+
 	set_vec(1,1,1);
 	set_vec(3,1,1);
 	set_vec(23,1,1);
-	
+
 	set_vec(3,1,3);
 	set_vec(3,2,3);
 	set_vec(3,4,3);
 	set_vec(3,4,7);
 	set_vec(3,8,3);
 	set_vec(3,8,7);
-	
+
 	set_vec(0,32,17);
 	set_vec(1,32,17);
 
@@ -1749,7 +1749,7 @@
 		my $bits = unpack("b*", $vector);
 		my $i = 0;
 		my $BASE = 8;
-	
+
 		print "vector length in bytes: ", length($vector), "\n";
 		@bytes = unpack("A8" x length($vector), $bits);
 		print "bits are: @bytes\n\n";
@@ -2125,7 +2125,7 @@
 		my($num, $unparsed) = strtod($str);
 		if (($str eq '') || ($unparsed != 0) || $!) {
 				return undef;
-			} 
+			}
 		else {
 			return $num;
 			}

Modified: perlfaq/trunk/perlfaq5.pod
==============================================================================
--- perlfaq/trunk/perlfaq5.pod	(original)
+++ perlfaq/trunk/perlfaq5.pod	Thu May  4 10:04:31 2006
@@ -170,7 +170,7 @@
 
 	if (defined(fileno(FH))
 		return (*FH, $base_name);
-	    } 
+	    }
 	else {
 		return ();
 	    }
@@ -209,7 +209,7 @@
 group or loop over them with for. It also avoids polluting the program
 with global variables and using symbolic references.
 
-=head2 How can I make a filehandle local to a subroutine?  How do I pass filehandles between subroutines?  How do I make an array of filehandles? 
+=head2 How can I make a filehandle local to a subroutine?  How do I pass filehandles between subroutines?  How do I make an array of filehandles?
 X<filehandle, local> X<filehandle, passing> X<filehandle, reference>
 
 As of perl5.6, open() autovivifies file and directory handles
@@ -227,12 +227,12 @@
 
 If you like, you can store these filehandles in an array or a hash.
 If you access them directly, they aren't simple scalars and you
-need to give C<print> a little help by placing the filehandle 
+need to give C<print> a little help by placing the filehandle
 reference in braces. Perl can only figure it out on its own when
 the filehandle reference is a simple scalar.
 
 	my @fhs = ( $fh1, $fh2, $fh3 );
-	
+
 	for( $i = 0; $i <= $#fhs; $i++ ) {
 		print {$fhs[$i]} "just another Perl answer, \n";
 		}
@@ -870,7 +870,7 @@
 		$term->setcc(VTIME, 1);
 		$term->setattr($fd_stdin, TCSANOW);
 		}
-	
+
 	sub cooked {
 		$term->setlflag($oterm);
 		$term->setcc(VTIME, 0);

Modified: perlfaq/trunk/perlfaq6.pod
==============================================================================
--- perlfaq/trunk/perlfaq6.pod	(original)
+++ perlfaq/trunk/perlfaq6.pod	Thu May  4 10:04:31 2006
@@ -26,9 +26,9 @@
 Describe what you're doing and how you're doing it, using normal Perl
 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) /meg;
+	# 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) /meg;
 
 =item Comments Inside the Regex
 
@@ -39,20 +39,20 @@
 
 C</x> lets you turn this:
 
-    s{<(?:[^>'"]*|".*?"|'.*?')+>}{}gs;
+	s{<(?:[^>'"]*|".*?"|'.*?')+>}{}gs;
 
 into this:
 
-    s{ <                    # opening angle bracket
-        (?:                 # Non-backreffing grouping paren
-             [^>'"] *       # 0 or more things that are neither > nor ' nor "
-                |           #    or else
-             ".*?"          # a section between double quotes (stingy match)
-                |           #    or else
-             '.*?'          # a section between single quotes (stingy match)
-        ) +                 #   all occurring one or more times
-       >                    # closing angle bracket
-    }{}gsx;                 # replace with nothing, i.e. delete
+	s{ <                    # opening angle bracket
+		(?:                 # Non-backreffing grouping paren
+			[^>'"] *        # 0 or more things that are neither > nor ' nor "
+				|           #    or else
+			".*?"           # a section between double quotes (stingy match)
+				|           #    or else
+			'.*?'           # a section between single quotes (stingy match)
+		) +                 #   all occurring one or more times
+		>                   # closing angle bracket
+	}{}gsx;                 # replace with nothing, i.e. delete
 
 It's still not quite so clear as prose, but it is very useful for
 describing the meaning of each part of the pattern.
@@ -65,8 +65,8 @@
 delimiters.  Selecting another delimiter can avoid quoting the
 delimiter within the pattern:
 
-    s/\/usr\/local/\/usr\/share/g;	# bad delimiter choice
-    s#/usr/local#/usr/share#g;		# better
+	s/\/usr\/local/\/usr\/share/g;	# bad delimiter choice
+	s#/usr/local#/usr/share#g;		# better
 
 =back
 
@@ -97,31 +97,31 @@
 than the default, or else we won't actually ever have a multiline
 record read in.
 
-    $/ = '';  		# read in more whole paragraph, not just one line
-    while ( <> ) {
-	while ( /\b([\w'-]+)(\s+\1)+\b/gi ) {  	# word starts alpha
-	    print "Duplicate $1 at paragraph $.\n";
+	$/ = '';  		# read in more whole paragraph, not just one line
+	while ( <> ) {
+		while ( /\b([\w'-]+)(\s+\1)+\b/gi ) {  	# word starts alpha
+			print "Duplicate $1 at paragraph $.\n";
+		}
 	}
-    }
 
 Here's code that finds sentences that begin with "From " (which would
 be mangled by many mailers):
 
-    $/ = '';  		# read in more whole paragraph, not just one line
-    while ( <> ) {
-	while ( /^From /gm ) { # /m makes ^ match next to \n
-	    print "leading from in paragraph $.\n";
+	$/ = '';  		# read in more whole paragraph, not just one line
+	while ( <> ) {
+		while ( /^From /gm ) { # /m makes ^ match next to \n
+		print "leading from in paragraph $.\n";
+		}
 	}
-    }
 
 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/sgm ) { # /s makes . cross line boundaries
-	    print "$1\n";
+	undef $/;  		# read in whole file, not just one line or paragraph
+	while ( <> ) {
+		while ( /START(.*?)END/sgm ) { # /s makes . cross line boundaries
+		    print "$1\n";
+		}
 	}
-    }
 
 =head2 How can I pull out lines between two patterns that are themselves on different lines?
 X<..>
@@ -129,11 +129,11 @@
 You can use Perl's somewhat exotic C<..> operator (documented in
 L<perlop>):
 
-    perl -ne 'print if /START/ .. /END/' file1 file2 ...
+	perl -ne 'print if /START/ .. /END/' file1 file2 ...
 
 If you wanted text and not lines, you would use
 
-    perl -0777 -ne 'print "$1\n" while /START(.*?)END/gs' file1 file2 ...
+	perl -0777 -ne 'print "$1\n" while /START(.*?)END/gs' file1 file2 ...
 
 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
@@ -141,13 +141,13 @@
 
 Here's another example of using C<..>:
 
-    while (<>) {
-        $in_header =   1  .. /^$/;
-        $in_body   = /^$/ .. eof();
+	while (<>) {
+		$in_header =   1  .. /^$/;
+		$in_body   = /^$/ .. eof();
 	# now choose between them
-    } continue {
-	reset if eof();		# fix $.
-    }
+	} continue {
+		reset if eof();		# fix $.
+	}
 
 =head2 I put a regular expression into $/ but it didn't work. What's wrong?
 X<$/, regexes in> X<$INPUT_RECORD_SEPARATOR, regexes in>
@@ -159,13 +159,14 @@
 
 If you have File::Stream, this is easy.
 
-			 use File::Stream;
-             my $stream = File::Stream->new(
-                  $filehandle,
-                  separator => qr/\s*,\s*/,
-                  );
+	use File::Stream;
+
+	my $stream = File::Stream->new(
+		$filehandle,
+		separator => qr/\s*,\s*/,
+		);
 
-			 print "$_\n" while <$stream>;
+	print "$_\n" while <$stream>;
 
 If you don't have File::Stream, you have to do a little more work.
 
@@ -173,25 +174,25 @@
 a buffer.  After you add to the buffer, you check if you have a
 complete line (using your regular expression).
 
-       local $_ = "";
-       while( sysread FH, $_, 8192, length ) {
-          while( s/^((?s).*?)your_pattern/ ) {
-             my $record = $1;
-             # do stuff here.
-          }
-       }
+	local $_ = "";
+	while( sysread FH, $_, 8192, length ) {
+		while( s/^((?s).*?)your_pattern/ ) {
+			my $record = $1;
+			# do stuff here.
+		}
+	}
 
  You can do the same thing with foreach and a match using the
  c flag and the \G anchor, if you do not mind your entire file
  being in memory at the end.
 
-       local $_ = "";
-       while( sysread FH, $_, 8192, length ) {
-          foreach my $record ( m/\G((?s).*?)your_pattern/gc ) {
-             # do stuff here.
-          }
-          substr( $_, 0, pos ) = "" if pos;
-       }
+	local $_ = "";
+	while( sysread FH, $_, 8192, length ) {
+		foreach my $record ( m/\G((?s).*?)your_pattern/gc ) {
+			# do stuff here.
+		}
+	substr( $_, 0, pos ) = "" if pos;
+	}
 
 
 =head2 How do I substitute case insensitively on the LHS while preserving case on the RHS?
@@ -201,49 +202,49 @@
 Here's a lovely Perlish solution by Larry Rosler.  It exploits
 properties of bitwise xor on ASCII strings.
 
-    $_= "this is a TEsT case";
+	$_= "this is a TEsT case";
 
-    $old = 'test';
-    $new = 'success';
+	$old = 'test';
+	$new = 'success';
 
-    s{(\Q$old\E)}
-     { uc $new | (uc $1 ^ $1) .
-	(uc(substr $1, -1) ^ substr $1, -1) x
-	    (length($new) - length $1)
-     }egi;
+	s{(\Q$old\E)}
+	{ uc $new | (uc $1 ^ $1) .
+		(uc(substr $1, -1) ^ substr $1, -1) x
+		(length($new) - length $1)
+	}egi;
 
-    print;
+	print;
 
 And here it is as a subroutine, modeled after the above:
 
-    sub preserve_case($$) {
-	my ($old, $new) = @_;
-	my $mask = uc $old ^ $old;
+	sub preserve_case($$) {
+		my ($old, $new) = @_;
+		my $mask = uc $old ^ $old;
 
-	uc $new | $mask .
-	    substr($mask, -1) x (length($new) - length($old))
+		uc $new | $mask .
+			substr($mask, -1) x (length($new) - length($old))
     }
 
-    $a = "this is a TEsT case";
-    $a =~ s/(test)/preserve_case($1, "success")/egi;
-    print "$a\n";
+	$a = "this is a TEsT case";
+	$a =~ s/(test)/preserve_case($1, "success")/egi;
+	print "$a\n";
 
 This prints:
 
-    this is a SUcCESS case
+	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, @_;
+	sub preserve_case {
+		my ($from, $to) = @_;
+		my ($lf, $lt) = map length, @_;
 
-    if ($lt < $lf) { $from = substr $from, 0, $lt }
-    else { $from .= substr $to, $lf }
+		if ($lt < $lf) { $from = substr $from, 0, $lt }
+		else { $from .= substr $to, $lf }
 
-    return uc $to | ($from ^ uc $from);
-  }
+		return uc $to | ($from ^ uc $from);
+		}
 
 This changes the sentence to "this is a SUcCess case."
 
@@ -315,11 +316,11 @@
 also that any regex special characters will be acted on unless you
 precede the substitution with \Q.  Here's an example:
 
-    $string = "Placido P. Octopus";
-    $regex  = "P.";
+	$string = "Placido P. Octopus";
+	$regex  = "P.";
 
-    $string =~ s/$regex/Polyp/;
-    # $string is now "Polypacido P. Octopus"
+	$string =~ s/$regex/Polyp/;
+	# $string is now "Polypacido P. Octopus"
 
 Because C<.> is special in regular expressions, and can match any
 single character, the regex C<P.> here has matched the <Pl> in the
@@ -327,11 +328,11 @@
 
 To escape the special meaning of C<.>, we use C<\Q>:
 
-    $string = "Placido P. Octopus";
-    $regex  = "P.";
+	$string = "Placido P. Octopus";
+	$regex  = "P.";
 
-    $string =~ s/\Q$regex/Polyp/;
-    # $string is now "Placido Polyp Octopus"
+	$string =~ s/\Q$regex/Polyp/;
+	# $string is now "Placido Polyp Octopus"
 
 The use of C<\Q> causes the <.> in the regex to be treated as a
 regular character, so that C<P.> matches a C<P> followed by a dot.
@@ -358,28 +359,28 @@
 
 For example, here's a "paragrep" program:
 
-    $/ = '';  # paragraph mode
-    $pat = shift;
-    while (<>) {
-        print if /$pat/o;
-    }
+	$/ = '';  # paragraph mode
+	$pat = shift;
+	while (<>) {
+		print if /$pat/o;
+	}
 
 =head2 How do I use a regular expression to strip C style comments from a file?
 
 While this actually can be done, it's much harder than you'd think.
 For example, this one-liner
 
-    perl -0777 -pe 's{/\*.*?\*/}{}gs' foo.c
+	perl -0777 -pe 's{/\*.*?\*/}{}gs' foo.c
 
 will work in many but not all cases.  You see, it's too simple-minded for
 certain kinds of C programs, in particular, those with what appear to be
 comments in quoted strings.  For that, you'd need something like this,
 created by Jeffrey Friedl and later modified by Fred Curtis.
 
-    $/ = undef;
-    $_ = <>;
-    s#/\*[^*]*\*+([^/*][^*]*\*+)*/|("(\\.|[^"\\])*"|'(\\.|[^'\\])*'|.[^/"'\\]*)#defined $2 ? $2 : ""#gse;
-    print;
+	$/ = undef;
+	$_ = <>;
+	s#/\*[^*]*\*+([^/*][^*]*\*+)*/|("(\\.|[^"\\])*"|'(\\.|[^'\\])*'|.[^/"'\\]*)#defined $2 ? $2 : ""#gse;
+	print;
 
 This could, of course, be more legibly written with the C</x> modifier, adding
 whitespace and comments.  Here it is expanded, courtesy of Fred Curtis.
@@ -423,7 +424,7 @@
 
 A slight modification also removes C++ comments:
 
-    s#/\*[^*]*\*+([^/*][^*]*\*+)*/|//[^\n]*|("(\\.|[^"\\])*"|'(\\.|[^'\\])*'|.[^/"'\\]*)#defined $2 ? $2 : ""#gse;
+	s#/\*[^*]*\*+([^/*][^*]*\*+)*/|//[^\n]*|("(\\.|[^"\\])*"|'(\\.|[^'\\])*'|.[^/"'\\]*)#defined $2 ? $2 : ""#gse;
 
 =head2 Can I use Perl regular expressions to match balanced text?
 X<regex, matching balanced test> X<regexp, matching balanced test>
@@ -466,9 +467,9 @@
 
 An example:
 
-        $s1 = $s2 = "I am very very cold";
-        $s1 =~ s/ve.*y //;      # I am cold
-        $s2 =~ s/ve.*?y //;     # I am very cold
+	$s1 = $s2 = "I am very very cold";
+	$s1 =~ s/ve.*y //;      # I am cold
+	$s2 =~ s/ve.*?y //;     # I am very cold
 
 Notice how the second substitution stopped matching as soon as it
 encountered "y ".  The C<*?> quantifier effectively tells the regular
@@ -481,11 +482,11 @@
 
 Use the split function:
 
-    while (<>) {
-	foreach $word ( split ) {
-	    # do something with $word here
+	while (<>) {
+		foreach $word ( split ) {
+			# do something with $word here
+		}
 	}
-    }
 
 Note that this isn't really a word in the English sense; it's just
 chunks of consecutive non-whitespace characters.
@@ -493,11 +494,11 @@
 To work with only alphanumeric sequences (including underscores), you
 might consider
 
-    while (<>) {
-	foreach $word (m/(\w+)/g) {
-	    # do something with $word here
+	while (<>) {
+		foreach $word (m/(\w+)/g) {
+			# do something with $word here
+		}
 	}
-    }
 
 =head2 How can I print out a word-frequency or line-frequency summary?
 
@@ -506,24 +507,26 @@
 apostrophes, rather than the non-whitespace chunk idea of a word given
 in the previous question:
 
-    while (<>) {
-	while ( /(\b[^\W_\d][\w'-]+\b)/g ) {   # misses "`sheep'"
-	    $seen{$1}++;
+	while (<>) {
+		while ( /(\b[^\W_\d][\w'-]+\b)/g ) {   # misses "`sheep'"
+			$seen{$1}++;
+		}
 	}
-    }
-    while ( ($word, $count) = each %seen ) {
-	print "$count $word\n";
-    }
+
+	while ( ($word, $count) = each %seen ) {
+		print "$count $word\n";
+		}
 
 If you wanted to do the same thing for lines, you wouldn't need a
 regular expression:
 
-    while (<>) {
-	$seen{$_}++;
-    }
-    while ( ($line, $count) = each %seen ) {
-	print "$count $line";
-    }
+	while (<>) {
+		$seen{$_}++;
+		}
+
+	while ( ($line, $count) = each %seen ) {
+		print "$count $line";
+	}
 
 If you want these output in a sorted order, see L<perlfaq4>: "How do I
 sort a hash (optionally by value instead of key)?".
@@ -544,15 +547,18 @@
 the regular expression for every iteration of the foreach()
 loop since it has no way to know what $pattern will be.
 
-    @patterns = qw( foo bar baz );
+	@patterns = qw( foo bar baz );
 
-    LINE: while( <> )
-    	{
+	LINE: while( <DATA> )
+		{
 		foreach $pattern ( @patterns )
 			{
-	    	print if /\b$pattern\b/i;
-	    	next LINE;
-	   		}
+			if( /\b$pattern\b/i )
+				{
+				print;
+				next LINE;
+				}
+			}
 		}
 
 The qr// operator showed up in perl 5.005.  It compiles a
@@ -562,15 +568,15 @@
 its pre-compiled form.  The rest of the script is the same,
 but faster.
 
-    @patterns = map { qr/\b$_\b/i } qw( foo bar baz );
+	@patterns = map { qr/\b$_\b/i } qw( foo bar baz );
 
-    LINE: while( <> )
-    	{
+	LINE: while( <> )
+		{
 		foreach $pattern ( @patterns )
 			{
-	    	print if /\b$pattern\b/i;
-	    	next LINE;
-	   		}
+			print if /\b$pattern\b/i;
+			next LINE;
+			}
 		}
 
 In some cases, you may be able to make several patterns into
@@ -579,8 +585,8 @@
 
 	$regex = join '|', qw( foo bar baz );
 
-    LINE: while( <> )
-    	{
+	LINE: while( <> )
+		{
 		print if /\b(?:$regex)\b/i;
 		}
 
@@ -826,32 +832,33 @@
 
 Here are a few ways, all painful, to deal with it:
 
-   $martian =~ s/([A-Z][A-Z])/ $1 /g; # Make sure adjacent "martian"
-                                      # bytes are no longer adjacent.
-   print "found GX!\n" if $martian =~ /GX/;
+	# Make sure adjacent "martian" bytes are no longer adjacent.
+	$martian =~ s/([A-Z][A-Z])/ $1 /g;
+
+	print "found GX!\n" if $martian =~ /GX/;
 
 Or like this:
 
-   @chars = $martian =~ m/([A-Z][A-Z]|[^A-Z])/g;
-   # above is conceptually similar to:     @chars = $text =~ m/(.)/g;
-   #
-   foreach $char (@chars) {
-       print "found GX!\n", last if $char eq 'GX';
-   }
+	@chars = $martian =~ m/([A-Z][A-Z]|[^A-Z])/g;
+	# above is conceptually similar to:     @chars = $text =~ m/(.)/g;
+	#
+	foreach $char (@chars) {
+	print "found GX!\n", last if $char eq 'GX';
+	}
 
 Or like this:
 
-   while ($martian =~ m/\G([A-Z][A-Z]|.)/gs) {  # \G probably unneeded
-       print "found GX!\n", last if $1 eq 'GX';
-   }
+	while ($martian =~ m/\G([A-Z][A-Z]|.)/gs) {  # \G probably unneeded
+		print "found GX!\n", last if $1 eq 'GX';
+		}
 
 Here's another, slightly less painful, way to do it from Benjamin
 Goldberg, who uses a zero-width negative look-behind assertion.
 
 	print "found GX!\n" if	$martian =~ m/
-		   (?<![A-Z])
-		   (?:[A-Z][A-Z])*?
-		   GX
+		(?<![A-Z])
+		(?:[A-Z][A-Z])*?
+		GX
 		/x;
 
 This succeeds if the "martian" character GX is in the string, and fails
@@ -870,69 +877,69 @@
 We don't have to hard-code patterns into the match operator (or
 anything else that works with regular expressions). We can put the
 pattern in a variable for later use.
- 
+
 The match operator is a double quote context, so you can interpolate
 your variable just like a double quoted string. In this case, you
 read the regular expression as user input and store it in C<$regex>.
 Once you have the pattern in C<$regex>, you use that variable in the
 match operator.
 
-    chomp( my $regex = <STDIN> );
-    
-    if( $string =~ m/$regex/ ) { ... }
+	chomp( my $regex = <STDIN> );
 
-Any regular expression special characters in C<$regex> are still 
+	if( $string =~ m/$regex/ ) { ... }
+
+Any regular expression special characters in C<$regex> are still
 special, and the pattern still has to be valid or Perl will complain.
 For instance, in this pattern there is an unpaired parenthesis.
 
 	my $regex = "Unmatched ( paren";
-	
+
 	"Two parens to bind them all" =~ m/$regex/;
-	
+
 When Perl compiles the regular expression, it treats the parenthesis
 as the start of a memory match. When it doesn't find the closing
 parenthesis, it complains:
 
-	Unmatched ( in regex; marked by <-- HERE in m/Unmatched ( <-- HERE  paren/ at script line 3.                                                               
+	Unmatched ( in regex; marked by <-- HERE in m/Unmatched ( <-- HERE  paren/ at script line 3.
 
-You can get around this in several ways depending on our situation. 
+You can get around this in several ways depending on our situation.
 First, if you don't want any of the characters in the string to be
 special, you can escape them with C<quotemeta> before you use the string.
 
-    chomp( my $regex = <STDIN> );
-  	$regex = quotemeta( $regex );
-  	
-    if( $string =~ m/$regex/ ) { ... }
+	chomp( my $regex = <STDIN> );
+	$regex = quotemeta( $regex );
+
+	if( $string =~ m/$regex/ ) { ... }
 
 You can also do this directly in the match operator using the C<\Q>
 and C<\E> sequences. The C<\Q> tells Perl where to start escaping
 special characters, and the C<\E> tells it where to stop (see L<perlop>
 for more details).
 
-    chomp( my $regex = <STDIN> );
-  	
-    if( $string =~ m/\Q$regex\E/ ) { ... }
+	chomp( my $regex = <STDIN> );
+
+	if( $string =~ m/\Q$regex\E/ ) { ... }
 
 Alternately, you can use C<qr//>, the regular expression quote operator (see
-L<perlop> for more details).  It quotes and perhaps compiles the pattern, 
+L<perlop> for more details).  It quotes and perhaps compiles the pattern,
 and you can apply regular expression flags to the pattern.
 
-    chomp( my $input = <STDIN> );
-  	
-    my $regex = qr/$input/is;
-    
-    $string =~ m/$regex/  # same as m/$input/is; 
+	chomp( my $input = <STDIN> );
+
+	my $regex = qr/$input/is;
+
+	$string =~ m/$regex/  # same as m/$input/is;
 
 You might also want to trap any errors by wrapping an C<eval> block
 around the whole thing.
 
-    chomp( my $input = <STDIN> );
-  	
-    eval { 
-    	if( $string =~ m/\Q$input\E/ ) { ... } 
-    	};
-    warn $@ if $@;
-    
+	chomp( my $input = <STDIN> );
+
+	eval {
+		if( $string =~ m/\Q$input\E/ ) { ... }
+		};
+	warn $@ if $@;
+
 Or...
 
 	my $regex = eval { qr/$input/is };

Modified: perlfaq/trunk/perlfaq8.pod
==============================================================================
--- perlfaq/trunk/perlfaq8.pod	(original)
+++ perlfaq/trunk/perlfaq8.pod	Thu May  4 10:04:31 2006
@@ -1014,9 +1014,9 @@
 the current process group of your controlling terminal as follows:
 
     use POSIX qw/getpgrp tcgetpgrp/;
-    
+
     # Some POSIX systems, such as Linux, can be
-    # without a /dev/tty at boot time. 
+    # without a /dev/tty at boot time.
     if (!open(TTY, "/dev/tty")) {
         print "no tty\n";
     } else {