📄 ch02_02.htm
字号:
<HTML><HEAD><TITLE>Recipe 2.1. Checking Whether a String Is a Valid Number (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:30:01Z"><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="ch02_01.htm"TITLE="2. Numbers"><LINKREL="prev"HREF="ch02_01.htm"TITLE="2.0. Introduction"><LINKREL="next"HREF="ch02_03.htm"TITLE="2.2. Comparing Floating-Point Numbers"></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="ch02_01.htm"TITLE="2.0. Introduction"><IMGSRC="../gifs/txtpreva.gif"ALT="Previous: 2.0. Introduction"BORDER="0"></A></TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><B><FONTFACE="ARIEL,HELVETICA,HELV,SANSERIF"SIZE="-1"><ACLASS="chapter"REL="up"HREF="ch02_01.htm"TITLE="2. Numbers"></A></FONT></B></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch02_03.htm"TITLE="2.2. Comparing Floating-Point Numbers"><IMGSRC="../gifs/txtnexta.gif"ALT="Next: 2.2. Comparing Floating-Point Numbers"BORDER="0"></A></TD></TR></TABLE></DIV><DIVCLASS="sect1"><H2CLASS="sect1"><ACLASS="title"NAME="ch02-36504">2.1. Checking Whether a String Is a Valid Number</A></H2><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch02-pgfId-69">Problem <ACLASS="indexterm"NAME="ch02-idx-1000007977-0"></A><ACLASS="indexterm"NAME="ch02-idx-1000007977-1"></A></A></H3><PCLASS="para">You want to check whether a string represents a valid number. This is a common problem when validating input, as in a CGI script.</P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch02-pgfId-75">Solution</A></H3><PCLASS="para"><ACLASS="indexterm"NAME="ch02-idx-1000007987-0"></A>Compare it against a regular expression that matches the kinds of numbers you're interested in.</P><PRECLASS="programlisting">if ($string =~ /PATTERN/) { # is a number} else { # is not}</PRE></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch02-pgfId-91">Discussion</A></H3><PCLASS="para">This problem gets to the heart of what we mean by a number. Even things that sound simple, like <EMCLASS="emphasis">integer</EM>, make you think hard about what you will accept ("Is a leading + for positive numbers optional, mandatory, or forbidden?"). The many ways that floating-point numbers can be represented could overheat your brain.</P><PCLASS="para">You must decide what you will and will not accept. Then, construct a regular expression to match those things alone. Here are some precooked solutions (the cookbook's equivalent of just-add-water meals) for most common cases.</P><PRECLASS="programlisting">warn "has nondigits" if /\D/;warn "not a natural number" unless /^\d+$/; # rejects -3warn "not an integer" unless /^-?\d+$/; # rejects +3warn "not an integer" unless /^[+-]?\d+$/;warn "not a decimal number" unless /^-?\d+\.?\d*$/; # rejects .2warn "not a decimal number" unless /^-?(?:\d+(?:\.\d*)?|\.\d+)$/;warn "not a C float" unless /^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/;</PRE><PCLASS="para">These lines do not catch the IEEE notations of "Infinity" and "NaN", but unless you're worried that IEEE committee members will stop by your workplace and beat you over the head with copies of the relevant standards documents, you can probably forget about these strange numbers.</P><PCLASS="para">If your number has leading or trailing whitespace, those patterns won't work. Either add the appropriate logic directly, or call the <CODECLASS="literal">trim</CODE> function from <ACLASS="xref"HREF="ch01_15.htm"TITLE="Trimming Blanks from the Ends of a String">Recipe 1.14</A>.</P><PCLASS="para">If you're on a POSIX system, Perl supports the <CODECLASS="literal">POSIX::strtod</CODE> function. Its semantics are cumbersome, so here's a <CODECLASS="literal">getnum</CODE> wrapper function for more convenient access. This function takes a string and returns the number it found or <CODECLASS="literal">undef</CODE> for input that isn't a C float. The <CODECLASS="literal">is_numeric</CODE> function is a front end to <CODECLASS="literal">getnum</CODE> for when you just want to say "Is this a float?"</P><PRECLASS="programlisting">sub getnum { use POSIX qw(strtod); my $str = shift; $str =~ s/^\s+//; $str =~ s/\s+$//; $! = 0; my($num, $unparsed) = strtod($str); if (($str eq '') || ($unparsed != 0) || $!) { return; } else { return $num; } } sub is_numeric { defined scalar &getnum } </PRE></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch02-pgfId-151">See Also</A></H3><PCLASS="para">The regular expression syntax in <EMCLASS="emphasis">perlre </EM>(1) and <ACLASS="olink"HREF="../prog/ch02_01.htm">Chapter 2</A> of <ACLASS="citetitle"HREF="../prog/index.htm"TITLE="Programming Perl"><CITECLASS="citetitle">Programming Perl</CITE></A>; your system's <ICLASS="filename">strtod</I> (3) manpage; the documentation for the standard POSIX module (also in <ACLASS="olink"HREF="../prog/ch07_01.htm">Chapter 7</A> of <ACLASS="citetitle"HREF="../prog/index.htm"TITLE="Programming Perl"><CITECLASS="citetitle">Programming Perl</CITE></A>) <ACLASS="indexterm"NAME="ch02-idx-1000007979-0"></A><ACLASS="indexterm"NAME="ch02-idx-1000007979-1"></A><ACLASS="indexterm"NAME="ch02-idx-1000007979-2"></A></P></DIV></DIV><DIVCLASS="htmlnav"><P></P><HRALIGN="LEFT"WIDTH="684"TITLE="footer"><TABLEWIDTH="684"BORDER="0"CELLSPACING="0"CELLPADDING="0"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch02_01.htm"TITLE="2.0. Introduction"><IMGSRC="../gifs/txtpreva.gif"ALT="Previous: 2.0. Introduction"BORDER="0"></A></TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><ACLASS="book"HREF="index.htm"TITLE="Perl Cookbook"><IMGSRC="../gifs/txthome.gif"ALT="Perl Cookbook"BORDER="0"></A></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch02_03.htm"TITLE="2.2. Comparing Floating-Point Numbers"><IMGSRC="../gifs/txtnexta.gif"ALT="Next: 2.2. Comparing Floating-Point Numbers"BORDER="0"></A></TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228">2.0. Introduction</TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><ACLASS="index"HREF="index/index.htm"TITLE="Book Index"><IMGSRC="../gifs/index.gif"ALT="Book Index"BORDER="0"></A></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228">2.2. Comparing Floating-Point Numbers</TD></TR></TABLE><HRALIGN="LEFT"WIDTH="684"TITLE="footer"><FONTSIZE="-1"></DIV<!-- LIBRARY NAV BAR --> <img src="../gifs/smnavbar.gif" usemap="#library-map" border="0" alt="Library Navigation Links"><p> <a href="copyrght.htm">Copyright © 2002</a> O'Reilly & Associates. All rights reserved.</font> </p> <map name="library-map"> <area shape="rect" coords="1,0,85,94" href="../index.htm"><area shape="rect" coords="86,1,178,103" href="../lwp/index.htm"><area shape="rect" coords="180,0,265,103" href="../lperl/index.htm"><area shape="rect" coords="267,0,353,105" href="../perlnut/index.htm"><area shape="rect" coords="354,1,446,115" href="../prog/index.htm"><area shape="rect" coords="448,0,526,132" href="../tk/index.htm"><area shape="rect" coords="528,1,615,119" href="../cookbook/index.htm"><area shape="rect" coords="617,0,690,135" href="../pxml/index.htm"></map> </BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -