⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 perlfaq4.html

📁 《Perl 5教程》及《perl常问问题集》
💻 HTML
📖 第 1 页 / 共 4 页
字号:
<P><HR><H3><A NAME="How_do_I_expand_function_calls_i">How do I expand function calls in a string?</A></H3>This is documented in <A HREF="../../tppmsgs/msgs0.htm#59" tppabs="http://www.perl.org/CPAN/doc/manual/html/pod/perlref.html">the perlref manpage</A>. In general, this is fraught with quoting and readability problems, but itis possible. To interpolate a subroutine call (in a list context) into astring:<P><PRE>    print &quot;My sub returned @{[mysub(1,2,3)]} that time.\n&quot;;</PRE><P>If you prefer scalar context, similar chicanery is also useful forarbitrary expressions:<P><PRE>    print &quot;That yields ${\($n + 5)} widgets\n&quot;;</PRE><P>See also ``How can <FONT SIZE=-1>I</FONT> expand variables in text strings?'' in this section of the <FONT SIZE=-1>FAQ.</FONT><P><P><HR><H3><A NAME="How_do_I_find_matching_nesting_a">How do I find matching/nesting anything?</A></H3>This isn't something that can be tackled in one regular expression, nomatter how complicated. To find something between two single characters, apattern like <CODE>/x([^x]*)x/</CODE> will get the intervening bits in $1. For multiple ones, then something morelike <CODE>/alpha(.*?)omega/</CODE> would be needed. But none of these deals with nested patterns, nor canthey. For that you'll have to write a parser.<P><P><HR><H3><A NAME="How_do_I_reverse_a_string_">How do I reverse a string?</A></H3>Use <CODE>reverse()</CODE> in a scalar context, as documented in<A HREF="../../tppmsgs/msgs0.htm#68" tppabs="http://www.perl.org/CPAN/doc/manual/html/pod/perlfunc.html#reverse">reverse</A>.<P><PRE>    $reversed = reverse $string;</PRE><P><P><HR><H3><A NAME="How_do_I_expand_tabs_in_a_string">How do I expand tabs in a string?</A></H3>You can do it the old-fashioned way:<P><PRE>    1 while $string =~ s/\t+/' ' x (length($&amp;) * 8 - length($`) % 8)/e;</PRE><P>Or you can just use the Text::Tabs module (part of the standard perldistribution).<P><PRE>    use Text::Tabs;    @expanded_lines = expand(@lines_with_tabs);</PRE><P><P><HR><H3><A NAME="How_do_I_reformat_a_paragraph_">How do I reformat a paragraph?</A></H3>Use Text::Wrap (part of the standard perl distribution):<P><PRE>    use Text::Wrap;    print wrap(&quot;\t&quot;, '  ', @paragraphs);</PRE><P>The paragraphs you give to Text::Wrap may not contain embedded newlines.Text::Wrap doesn't justify the lines (flush-right).<P><P><HR><H3><A NAME="How_can_I_access_change_the_firs">How can I access/change the first N letters of a string?</A></H3>There are many ways. If you just want to grab a copy, use substr:<P><PRE>    $first_byte = substr($a, 0, 1);</PRE><P>If you want to modify part of a string, the simplest way is often to use<CODE>substr()</CODE> as an lvalue:<P><PRE>    substr($a, 0, 3) = &quot;Tom&quot;;</PRE><P>Although those with a regexp kind of thought process will likely prefer<P><PRE>    $a =~ s/^.../Tom/;</PRE><P><P><HR><H3><A NAME="How_do_I_change_the_Nth_occurren">How do I change the Nth occurrence of something?</A></H3>You have to keep track. For example, let's say you want to change the fifthoccurrence of ``whoever'' or ``whomever'' into ``whosoever'' or``whomsoever'', case insensitively.<P><PRE>    $count = 0;    s{((whom?)ever)}{        ++$count == 5           # is it the 5th?            ? &quot;${2}soever&quot;      # yes, swap            : $1                # renege and leave it there    }igex;</PRE><P><P><HR><H3><A NAME="How_can_I_count_the_number_of_oc">How can I count the number of occurrences of a substring within a string?</A></H3>There are a number of ways, with varying efficiency: If you want a count of a certain single character <FONT SIZE=-1>(X)</FONT> within a string, you can use the<CODE>tr///</CODE> function like so:<P><PRE>    $string = &quot;ThisXlineXhasXsomeXx'sXinXit&quot;:    $count = ($string =~ tr/X//);    print &quot;There are $count X charcters in the string&quot;;</PRE><P>This is fine if you are just looking for a single character. However, ifyou are trying to count multiple character substrings within a largerstring, <CODE>tr///</CODE> won't work. What you can do is wrap a <CODE>while()</CODE> loop around aglobal pattern match. For example, let's count negative integers:<P><PRE>    $string = &quot;-9 55 48 -2 23 -76 4 14 -44&quot;;    while ($string =~ /-\d+/g) { $count++ }    print &quot;There are $count negative numbers in the string&quot;;</PRE><P><P><HR><H3><A NAME="How_do_I_capitalize_all_the_word">How do I capitalize all the words on one line?</A></H3>To make the first letter of each word upper case:<P><PRE>        $line =~ s/\b(\w)/\U$1/g;</PRE><P>This has the strange effect of turning ``<CODE>don't do it</CODE>'' into ``<CODE>Don'TDo It</CODE>''. Sometimes you might want this, instead (Suggested by Brian Foy &lt;<A HREF="MAILTO:comdog@computerdog.com">comdog@computerdog.com</A>&gt;):<P><PRE>    $string =~ s/ (                 (^\w)    #at the beginning of the line                   |      # or                 (\s\w)   #preceded by whitespace                   )                /\U$1/xg;    $string =~ /([\w']+)/\u\L$1/g;</PRE><P>To make the whole line upper case:<P><PRE>        $line = uc($line);</PRE><P>To force each word to be lower case, with the first letter upper case:<P><PRE>        $line =~ s/(\w+)/\u\L$1/g;</PRE><P><P><HR><H3><A NAME="How_can_I_split_a_character_de">How can I split a [character] delimited string except when inside[character]? (Comma-separated files)</A></H3>Take the example case of trying to split a string that is comma-separatedinto its different fields. (We'll pretend you said comma-separated, notcomma-delimited, which is different and almost never what you mean.) Youcan't use <CODE>split(/,/)</CODE> because you shouldn't split if the comma is inside quotes. For example,take a data line like this:<P><PRE>    SAR001,&quot;&quot;,&quot;Cimetrix, Inc&quot;,&quot;Bob Smith&quot;,&quot;CAM&quot;,N,8,1,0,7,&quot;Error, Core Dumped&quot;</PRE><P>Due to the restriction of the quotes, this is a fairly complex problem.Thankfully, we have Jeffrey Friedl, author of a highly recommended book onregular expressions, to handle these for us. He suggests (assuming yourstring is contained in $text):<P><PRE>     @new = ();     push(@new, $+) while $text =~ m{         &quot;([^\&quot;\\]*(?:\\.[^\&quot;\\]*)*)&quot;,?  # groups the phrase inside the quotes       | ([^,]+),?       | ,     }gx;     push(@new, undef) if substr($text,-1,1) eq ',';</PRE><P>If you want to represent quotation marks inside a quotation-mark-delimitedfield, escape them with backslashes (eg,C<``like \''this\``''). Unescaping them is a task addressed earlier in thissection.<P>Alternatively, the Text::ParseWords module (part of the standard perldistribution) lets you say:<P><PRE>    use Text::ParseWords;    @new = quotewords(&quot;,&quot;, 0, $text);</PRE><P><P><HR><H3><A NAME="How_do_I_strip_blank_space_from_">How do I strip blank space from the beginning/end of a string?</A></H3>The simplest approach, albeit not the fastest, is probably like this:<P><PRE>    $string =~ s/^\s*(.*?)\s*$/$1/;</PRE><P>It would be faster to do this in two steps:<P><PRE>    $string =~ s/^\s+//;    $string =~ s/\s+$//;</PRE><P>Or more nicely written as:<P><PRE>    for ($string) {        s/^\s+//;        s/\s+$//;    }</PRE><P><P><HR><H3><A NAME="How_do_I_extract_selected_column">How do I extract selected columns from a string?</A></H3>Use <CODE>substr()</CODE> or <CODE>unpack(),</CODE> both documented in <A HREF="../../tppmsgs/msgs0.htm#68" tppabs="http://www.perl.org/CPAN/doc/manual/html/pod/perlfunc.html">the perlfunc manpage</A>.<P><P><HR><H3><A NAME="How_do_I_find_the_soundex_value_">How do I find the soundex value of a string?</A></H3>Use the standard Text::Soundex module distributed with perl.<P><P><HR><H3><A NAME="How_can_I_expand_variables_in_te">How can I expand variables in text strings?</A></H3>Let's assume that you have a string like:<P><PRE>    $text = 'this has a $foo in it and a $bar';    $text =~ s/\$(\w+)/${$1}/g;</PRE><P>Before version 5 of perl, this had to be done with a double-evalsubstitution:<P><PRE>    $text =~ s/(\$\w+)/$1/eeg;</PRE><P>Which is bizarre enough that you'll probably actually need an <FONT SIZE=-1>EEG</FONT> afterwards. :-)<P>See also ``How do <FONT SIZE=-1>I</FONT> expand function calls in a string?'' in this section of the <FONT SIZE=-1>FAQ.</FONT><P><P><HR><H3><A NAME="What_s_wrong_with_always_quoting">What's wrong with always quoting "$vars"?</A></H3>The problem is that those double-quotes force stringification, coercingnumbers and references into strings, even when you don't want them to be.<P>If you get used to writing odd things like these:<P><PRE>    print &quot;$var&quot;;       # BAD    $new = &quot;$old&quot;;      # BAD    somefunc(&quot;$var&quot;);   # BAD</PRE><P>You'll be in trouble. Those should (in 99.8% of the cases) be the simplerand more direct:<P><PRE>    print $var;    $new = $old;    somefunc($var);</PRE><P>Otherwise, besides slowing you down, you're going to break code when thething in the scalar is actually neither a string nor a number, but areference:<P><PRE>    func(\@array);    sub func {        my $aref = shift;        my $oref = &quot;$aref&quot;;  # WRONG    }</PRE><P>You can also get into subtle problems on those few operations in Perl thatactually do care about the difference between a string and a number, suchas the magical <CODE>++</CODE> autoincrement operator or the <CODE>syscall()</CODE> function.<P><P><HR><H3><A NAME="Why_don_t_my_HERE_documents_wo">Why don't my <<HERE documents work?</A></H3>Check for these three things:<P><OL><LI><STRONG><A NAME="item_There_must_be_no_space_after_the"> There must be no space after the << part.</A></STRONG><LI><STRONG><A NAME="item_There_probably_should_be_a_sem"> There (probably) should be a semicolon at the end.</A></STRONG><LI><STRONG><A NAME="item_You_can_t_easily_have_any_spac"> You can't (easily) have any space in front of the tag.</A></STRONG></OL><P><HR><H2><A NAME="Data_Arrays">Data: Arrays</A></H2><P><HR><H3><A NAME="What_is_the_difference_between_">What is the difference between $array[1] and @array[1]?</A></H3>The former is a scalar value, the latter an array slice, which makes it alist with one (scalar) value. You should use $ when you want a scalar value(most of the time) and @ when you want a list with one scalar value in it(very, very rarely; nearly never, in fact).<P>Sometimes it doesn't make a difference, but sometimes it does. For example,compare:<P><PRE>    $good[0] = `some program that outputs several lines`;</PRE><P>with<P><PRE>    @bad[0]  = `same program that outputs several lines`;</PRE><P>The <STRONG>-w</STRONG> flag will warn you about these matters.<P><P><HR><H3><A NAME="How_can_I_extract_just_the_uniqu">How can I extract just the unique elements of an array?</A></H3>There are several possible ways, depending on whether the array is orderedand whether you wish to preserve the ordering.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -