📄 perlfaq4.1
字号:
To force each word to be lower case, with the first letter upper case:.PP.Vb 1\& $line =~ s/(\ew+)/\eu\eL$1/g;.Ve.PPYou can (and probably should) enable locale awareness of thosecharacters by placing a \f(CW\*(C`use locale\*(C'\fR pragma in your program.See perllocale for endless details on locales..PPThis is sometimes referred to as putting something into \*(L"titlecase\*(R", but that's not quite accurate. Consider the propercapitalization of the movie \fIDr. Strangelove or: How I Learned toStop Worrying and Love the Bomb\fR, for example..PPDamian Conway's Text::Autoformat module provides some smartcase transformations:.PP.Vb 3\& use Text::Autoformat;\& my $x = "Dr. Strangelove or: How I Learned to Stop ".\& "Worrying and Love the Bomb";\&\& print $x, "\en";\& for my $style (qw( sentence title highlight )) {\& print autoformat($x, { case => $style }), "\en";\& }.Ve.Sh "How can I split a [character] delimited string except when inside [character]?".IX Subsection "How can I split a [character] delimited string except when inside [character]?"Several modules can handle this sort of parsing\*(--\f(CW\*(C`Text::Balanced\*(C'\fR,\&\f(CW\*(C`Text::CSV\*(C'\fR, \f(CW\*(C`Text::CSV_XS\*(C'\fR, and \f(CW\*(C`Text::ParseWords\*(C'\fR, among others..PPTake the example case of trying to split a string that iscomma-separated into its different fields. You can't use \f(CW\*(C`split(/,/)\*(C'\fRbecause you shouldn't split if the comma is inside quotes. Forexample, take a data line like this:.PP.Vb 1\& SAR001,"","Cimetrix, Inc","Bob Smith","CAM",N,8,1,0,7,"Error, Core Dumped".Ve.PPDue to the restriction of the quotes, this is a fairly complexproblem. Thankfully, we have Jeffrey Friedl, author of\&\fIMastering Regular Expressions\fR, to handle these for us. Hesuggests (assuming your string is contained in \f(CW$text\fR):.PP.Vb 7\& @new = ();\& push(@new, $+) while $text =~ m{\& "([^\e"\e\e]*(?:\e\e.[^\e"\e\e]*)*)",? # groups the phrase inside the quotes\& | ([^,]+),?\& | ,\& }gx;\& push(@new, undef) if substr($text,\-1,1) eq \*(Aq,\*(Aq;.Ve.PPIf you want to represent quotation marks inside aquotation-mark-delimited field, escape them with backslashes (eg,\&\f(CW"like \e"this\e""\fR..PPAlternatively, the \f(CW\*(C`Text::ParseWords\*(C'\fR module (part of the standardPerl distribution) lets you say:.PP.Vb 2\& use Text::ParseWords;\& @new = quotewords(",", 0, $text);.Ve.Sh "How do I strip blank space from the beginning/end of a string?".IX Subsection "How do I strip blank space from the beginning/end of a string?"(contributed by brian d foy).PPA substitution can do this for you. For a single line, you want toreplace all the leading or trailing whitespace with nothing. Youcan do that with a pair of substitutions..PP.Vb 2\& s/^\es+//;\& s/\es+$//;.Ve.PPYou can also write that as a single substitution, although it turnsout the combined statement is slower than the separate ones. Thatmight not matter to you, though..PP.Vb 1\& s/^\es+|\es+$//g;.Ve.PPIn this regular expression, the alternation matches either at thebeginning or the end of the string since the anchors have a lowerprecedence than the alternation. With the \f(CW\*(C`/g\*(C'\fR flag, the substitutionmakes all possible matches, so it gets both. Remember, the trailingnewline matches the \f(CW\*(C`\es+\*(C'\fR, and the \f(CW\*(C`$\*(C'\fR anchor can match to thephysical end of the string, so the newline disappears too. Just addthe newline to the output, which has the added benefit of preserving\&\*(L"blank\*(R" (consisting entirely of whitespace) lines which the \f(CW\*(C`^\es+\*(C'\fRwould remove all by itself..PP.Vb 5\& while( <> )\& {\& s/^\es+|\es+$//g;\& print "$_\en";\& }.Ve.PPFor a multi-line string, you can apply the regular expressionto each logical line in the string by adding the \f(CW\*(C`/m\*(C'\fR flag (for\&\*(L"multi-line\*(R"). With the \f(CW\*(C`/m\*(C'\fR flag, the \f(CW\*(C`$\*(C'\fR matches \fIbefore\fR anembedded newline, so it doesn't remove it. It still removes thenewline at the end of the string..PP.Vb 1\& $string =~ s/^\es+|\es+$//gm;.Ve.PPRemember that lines consisting entirely of whitespace will disappear,since the first part of the alternation can match the entire stringand replace it with nothing. If need to keep embedded blank lines,you have to do a little more work. Instead of matching any whitespace(since that includes a newline), just match the other whitespace..PP.Vb 1\& $string =~ s/^[\et\ef ]+|[\et\ef ]+$//mg;.Ve.Sh "How do I pad a string with blanks or pad a number with zeroes?".IX Subsection "How do I pad a string with blanks or pad a number with zeroes?"In the following examples, \f(CW$pad_len\fR is the length to which you wishto pad the string, \f(CW$text\fR or \f(CW$num\fR contains the string to be padded,and \f(CW$pad_char\fR contains the padding character. You can use a singlecharacter string constant instead of the \f(CW$pad_char\fR variable if youknow what it is in advance. And in the same way you can use an integer inplace of \f(CW$pad_len\fR if you know the pad length in advance..PPThe simplest method uses the \f(CW\*(C`sprintf\*(C'\fR function. It can pad on the leftor right with blanks and on the left with zeroes and it will nottruncate the result. The \f(CW\*(C`pack\*(C'\fR function can only pad strings on theright with blanks and it will truncate the result to a maximum length of\&\f(CW$pad_len\fR..PP.Vb 3\& # 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);.Ve.PPIf you need to pad with a character other than blank or zero you can useone of the following methods. They all generate a pad string with the\&\f(CW\*(C`x\*(C'\fR operator and combine that with \f(CW$text\fR. These methods donot truncate \f(CW$text\fR..PPLeft and right padding with any character, creating a new string:.PP.Vb 2\& $padded = $pad_char x ( $pad_len \- length( $text ) ) . $text;\& $padded = $text . $pad_char x ( $pad_len \- length( $text ) );.Ve.PPLeft and right padding with any character, modifying \f(CW$text\fR directly:.PP.Vb 2\& substr( $text, 0, 0 ) = $pad_char x ( $pad_len \- length( $text ) );\& $text .= $pad_char x ( $pad_len \- length( $text ) );.Ve.Sh "How do I extract selected columns from a string?".IX Subsection "How do I extract selected columns from a string?"(contributed by brian d foy).PPIf you know where the columns that contain the data, you canuse \f(CW\*(C`substr\*(C'\fR to extract a single column..PP.Vb 1\& my $column = substr( $line, $start_column, $length );.Ve.PPYou can use \f(CW\*(C`split\*(C'\fR if the columns are separated by whitespace orsome other delimiter, as long as whitespace or the delimiter cannotappear as part of the data..PP.Vb 3\& my $line = \*(Aq fred barney betty \*(Aq;\& my @columns = split /\es+/, $line;\& # ( \*(Aq\*(Aq, \*(Aqfred\*(Aq, \*(Aqbarney\*(Aq, \*(Aqbetty\*(Aq );\&\& my $line = \*(Aqfred||barney||betty\*(Aq;\& my @columns = split /\e|/, $line;\& # ( \*(Aqfred\*(Aq, \*(Aq\*(Aq, \*(Aqbarney\*(Aq, \*(Aq\*(Aq, \*(Aqbetty\*(Aq );.Ve.PPIf you want to work with comma-separated values, don't do this sincethat format is a bit more complicated. Use one of the modules thathandle that fornat, such as \f(CW\*(C`Text::CSV\*(C'\fR, \f(CW\*(C`Text::CSV_XS\*(C'\fR, or\&\f(CW\*(C`Text::CSV_PP\*(C'\fR..PPIf you want to break apart an entire line of fixed columns, you can use\&\f(CW\*(C`unpack\*(C'\fR with the A (\s-1ASCII\s0) format. by using a number after the formatspecifier, you can denote the column width. See the \f(CW\*(C`pack\*(C'\fR and \f(CW\*(C`unpack\*(C'\fRentries in perlfunc for more details..PP.Vb 1\& my @fields = unpack( $line, "A8 A8 A8 A16 A4" );.Ve.PPNote that spaces in the format argument to \f(CW\*(C`unpack\*(C'\fR do not denote literalspaces. If you have space separated data, you may want \f(CW\*(C`split\*(C'\fR instead..Sh "How do I find the soundex value of a string?".IX Subsection "How do I find the soundex value of a string?"(contributed by brian d foy).PPYou can use the Text::Soundex module. If you want to do fuzzy or closematching, you might also try the \f(CW\*(C`String::Approx\*(C'\fR, and\&\f(CW\*(C`Text::Metaphone\*(C'\fR, and \f(CW\*(C`Text::DoubleMetaphone\*(C'\fR modules..Sh "How can I expand variables in text strings?".IX Subsection "How can I expand variables in text strings?"(contributed by brian d foy).PPIf you can avoid it, don't, or if you can use a templating system,such as \f(CW\*(C`Text::Template\*(C'\fR or \f(CW\*(C`Template\*(C'\fR Toolkit, do that instead. Youmight even be able to get the job done with \f(CW\*(C`sprintf\*(C'\fR or \f(CW\*(C`printf\*(C'\fR:.PP.Vb 1\& my $string = sprintf \*(AqSay hello to %s and %s\*(Aq, $foo, $bar;.Ve.PPHowever, for the one-off simple case where I don't want to pull out afull templating system, I'll use a string that has two Perl scalarvariables in it. In this example, I want to expand \f(CW$foo\fR and \f(CW$bar\fRto their variable's values:.PP.Vb 3\& my $foo = \*(AqFred\*(Aq;\& my $bar = \*(AqBarney\*(Aq;\& $string = \*(AqSay hello to $foo and $bar\*(Aq;.Ve.PPOne way I can do this involves the substitution operator and a double\&\f(CW\*(C`/e\*(C'\fR flag. The first \f(CW\*(C`/e\*(C'\fR evaluates \f(CW$1\fR on the replacement side andturns it into \f(CW$foo\fR. The second /e starts with \f(CW$foo\fR and replacesit with its value. \f(CW$foo\fR, then, turns into 'Fred', and that's finallywhat's left in the string:.PP.Vb 1\& $string =~ s/(\e$\ew+)/$1/eeg; # \*(AqSay hello to Fred and Barney\*(Aq.Ve.PPThe \f(CW\*(C`/e\*(C'\fR will also silently ignore violations of strict, replacingundefined variable names with the empty string. Since I'm using the\&\f(CW\*(C`/e\*(C'\fR flag (twice even!), I have all of the same security problems I have with \f(CW\*(C`eval\*(C'\fR in its string form. If there's something odd in\&\f(CW$foo\fR, perhaps something like \f(CW\*(C`@{[ system "rm \-rf /" ]}\*(C'\fR, thenI could get myself in trouble..PPTo get around the security problem, I could also pull the values froma hash instead of evaluating variable names. Using a single \f(CW\*(C`/e\*(C'\fR, Ican check the hash to ensure the value exists, and if it doesn't, Ican replace the missing value with a marker, in this case \f(CW\*(C`???\*(C'\fR tosignal that I missed something:.PP.Vb 1\& my $string = \*(AqThis has $foo and $bar\*(Aq;\& \& my %Replacements = (\& foo => \*(AqFred\*(Aq,\& );\&\& # $string =~ s/\e$(\ew+)/$Replacements{$1}/g;\& $string =~ s/\e$(\ew+)/\& exists $Replacements{$1} ? $Replacements{$1} : \*(Aq???\*(Aq\& /eg;\&\& print $string;.Ve.ie n .Sh "What's wrong with always quoting ""$vars""?".el .Sh "What's wrong with always quoting ``$vars''?".IX Subsection "What's wrong with always quoting $vars?"The problem is that those double-quotes forcestringification\*(--coercing numbers and references into strings\*(--evenwhen you don't want them to be strings. Think of it this way:double-quote expansion is used to produce new strings. If you alreadyhave a string, why do you need more?.PPIf you get used to writing odd things like these:.PP.Vb 3\& print "$var"; # BAD\& $new = "$old"; # BAD\& somefunc("$var"); # BAD.Ve.PPYou'll be in trouble. Those should (in 99.8% of the cases) bethe simpler and more direct:.PP.Vb 3\& print $var;\& $new = $old;\& somefunc($var);.Ve.PPOtherwise, besides slowing you down, you're going to break code whenthe thing in the scalar is actually neither a string nor a number, buta reference:.PP.Vb 5\& func(\e@array);\& sub func {\& my $aref = shift;\& my $oref = "$aref"; # WRONG\& }.Ve.PPYou can also get into subtle problems on those few operations in Perlthat actually do care about the difference between a string and anumber, such as the magical \f(CW\*(C`++\*(C'\fR autoincrement operator or the\&\fIsyscall()\fR function..PPStringification also destroys arrays..PP.Vb 3\& @lines = \`command\`;\& print "@lines"; # WRONG \- extra blanks\& print @lines; # right.Ve.Sh "Why don't my <<\s-1HERE\s0 documents work?".IX Subsection "Why don't my <<HERE documents work?"Check for these three things:.IP "There must be no space after the << part." 4.IX Item "There must be no space after the << part.".PD 0.IP "There (probably) should be a semicolon at the end." 4.IX Item "There (probably) should be a semicolon at the end.".IP "You can't (easily) have any space in front of the tag." 4.IX Item "You can't (easily) have any space in front of the tag.".PD.PPIf you want to indent the text in the here document, youcan do this:.PP.Vb 5\& # all in one
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -