📄 ch08_04.htm
字号:
<HTML><HEAD><TITLE>Recipe 8.3. Processing Every Word in a File (Perl Cookbook)</TITLE><METANAME="DC.title"CONTENT="Perl Cookbook"><METANAME="DC.creator"CONTENT="Tom Christiansen & Nathan Torkington"><METANAME="DC.publisher"CONTENT="O'Reilly & Associates, Inc."><METANAME="DC.date"CONTENT="1999-07-02T01:38:39Z"><METANAME="DC.type"CONTENT="Text.Monograph"><METANAME="DC.format"CONTENT="text/html"SCHEME="MIME"><METANAME="DC.source"CONTENT="1-56592-243-3"SCHEME="ISBN"><METANAME="DC.language"CONTENT="en-US"><METANAME="generator"CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"><LINKREV="made"HREF="mailto:online-books@oreilly.com"TITLE="Online Books Comments"><LINKREL="up"HREF="ch08_01.htm"TITLE="8. File Contents"><LINKREL="prev"HREF="ch08_03.htm"TITLE="8.2. Counting Lines (or Paragraphs or Records) in a File"><LINKREL="next"HREF="ch08_05.htm"TITLE="8.4. Reading a File Backwards by Line or Paragraph"></HEAD><BODYBGCOLOR="#FFFFFF"><img alt="Book Home" border="0" src="gifs/smbanner.gif" usemap="#banner-map" /><map name="banner-map"><area shape="rect" coords="1,-2,616,66" href="index.htm" alt="Perl Cookbook"><area shape="rect" coords="629,-11,726,25" href="jobjects/fsearch.htm" alt="Search this book" /></map><div class="navbar"><p><TABLEWIDTH="684"BORDER="0"CELLSPACING="0"CELLPADDING="0"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch08_03.htm"TITLE="8.2. Counting Lines (or Paragraphs or Records) in a File"><IMGSRC="../gifs/txtpreva.gif"ALT="Previous: 8.2. Counting Lines (or Paragraphs or Records) in a File"BORDER="0"></A></TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><B><FONTFACE="ARIEL,HELVETICA,HELV,SANSERIF"SIZE="-1"><ACLASS="chapter"REL="up"HREF="ch08_01.htm"TITLE="8. File Contents"></A></FONT></B></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch08_05.htm"TITLE="8.4. Reading a File Backwards by Line or Paragraph"><IMGSRC="../gifs/txtnexta.gif"ALT="Next: 8.4. Reading a File Backwards by Line or Paragraph"BORDER="0"></A></TD></TR></TABLE></DIV><DIVCLASS="sect1"><H2CLASS="sect1"><ACLASS="title"NAME="ch08-chap08_processing_0">8.3. Processing Every Word in a File</A></H2><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch08-pgfId-324">Problem<ACLASS="indexterm"NAME="ch08-idx-1000004629-0"></A><ACLASS="indexterm"NAME="ch08-idx-1000004629-1"></A></A></H3><PCLASS="para">You need to do something to every word in a file, similar to the <CODECLASS="literal">foreach</CODE> function of <EMCLASS="emphasis">csh</EM>.</P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch08-pgfId-330">Solution</A></H3><PCLASS="para">Either <CODECLASS="literal">split</CODE><ACLASS="indexterm"NAME="ch08-idx-1000004635-0"></A> each line on whitespace:</P><PRECLASS="programlisting">while (<>) { for $chunk (split) { # do something with $chunk }}</PRE><PCLASS="para">Or use the <CODECLASS="literal">m//g</CODE> operator to pull out one chunk at a time:</P><PRECLASS="programlisting">while (<>) { while ( /(\w[\w'-]*)/g ) { # do something with $1 }}</PRE></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch08-pgfId-358">Discussion</A></H3><PCLASS="para">Decide what you mean by "word." Sometimes you want anything but whitespace, sometimes you only want program identifiers, and sometimes you want English words. Your definition governs which regular expression to use.</P><PCLASS="para">The preceding two approaches work differently. Patterns are used in the first approach to decide what is <EMCLASS="emphasis">not</EM> a word. In the second, they're used to decide what <EMCLASS="emphasis">is</EM> a word.</P><PCLASS="para">With these techniques, it's easy to make a word frequency counter. Use a hash to store how many times each word has been seen:</P><PRECLASS="programlisting"># Make a word frequency count%seen = ();while (<>) { while ( /(\w['\w-]*)/g ) { $seen{lc $1}++; }}# output hash in a descending numeric sort of its valuesforeach $word ( sort { $seen{$b} <=> $seen{$a} } keys %seen) { printf "%5d %s\n", $seen{$word}, $word;}</PRE><PCLASS="para">To make the example program count line frequency instead of word frequency, omit the second <CODECLASS="literal">while</CODE> loop and do <CODECLASS="literal">$seen{lc</CODE> <CODECLASS="literal">$_}++</CODE> instead:</P><PRECLASS="programlisting"># Line frequency count%seen = ();while (<>) { $seen{lc $_}++;}foreach $line ( sort { $seen{$b} <=> $seen{$a} } keys %seen ) { printf "%5d %s", $seen{$line}, $line;}</PRE><PCLASS="para">Odd things that may need to be considered as words include "M.I.T.", "Micro$oft", "o'clock", "49ers", "street-wise", "and/or", "&", "c/o", "St.", "Tsch
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -