<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" version="2.0">

<channel>
	<title>Flagrant Badassery</title>
	
	<link>http://blog.stevenlevithan.com</link>
	<description>A JavaScript and regular expression centric blog</description>
	<lastBuildDate>Tue, 09 Feb 2010 08:18:45 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/badassery" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="badassery" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.feedburner.com%2Fbadassery" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fbadassery" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://feeds.my.aol.com/add.jsp?url=http%3A%2F%2Ffeeds.feedburner.com%2Fbadassery" src="http://o.aolcdn.com/favorites.my.aol.com/webmaster/ffclient/webroot/locale/en-US/images/myAOLButtonSmall.gif">Subscribe with My AOL</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.bloglines.com/sub/http://feeds.feedburner.com/badassery" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fbadassery" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fbadassery" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fbadassery" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><item>
		<title>Validating and Formatting Phone Numbers (a Comprehensive Guide)</title>
		<link>http://blog.stevenlevithan.com/archives/validate-phone-number</link>
		<comments>http://blog.stevenlevithan.com/archives/validate-phone-number#comments</comments>
		<pubDate>Tue, 09 Feb 2010 06:57:36 +0000</pubDate>
		<dc:creator>Steven Levithan</dc:creator>
				<category><![CDATA[Books]]></category>
		<category><![CDATA[Regular Expressions]]></category>
		<category><![CDATA[validation]]></category>

		<guid isPermaLink="false">http://blog.stevenlevithan.com/?p=275</guid>
		<description><![CDATA[

Following are a couple recipes I wrote for Regular Expressions Cookbook, composing a fairly comprehensive guide to validating and formatting North American and international phone numbers using regular expressions. The regexes in these recipes are all pretty straightforward, but hopefully this gives an example of the depth you can expect from the book.

For more than [...]]]></description>
			<content:encoded><![CDATA[<a href="http://www.amazon.com/dp/0596520689/?tag=slfb-20"><img class="right" src="http://oreilly.com/catalog/covers/9780596520687_cat.gif" alt="Book cover: Regular Expressions Cookbook"></a>

<p>Following are a couple recipes I wrote for <em><a href="http://www.amazon.com/dp/0596520689/?tag=slfb-20">Regular Expressions Cookbook</a></em>, composing a fairly comprehensive guide to validating and formatting North American and international phone numbers using regular expressions. The regexes in these recipes are all pretty straightforward, but hopefully this gives an example of the depth you can expect from the book.</p>

<p>For more than 100 detailed regular expression recipes that include equal coverage for eight programming languages (C#, Java, JavaScript, Perl, PHP, Python, Ruby, and VB.NET), get your very own copy of <em><a href="http://www.amazon.com/dp/0596520689/?tag=slfb-20">Regular Expressions Cookbook</a></em>.  Also available in <a href="http://www.books.ru/shop/search?query=978-5-93286-181-3">Russian</a>.</p>

<ul>
	<li><a href="#r4-2">Validate and Format North American Phone Numbers</a>
		<ul>
			<li>Variations:
				<ul>
					<li><a href="#r4-2-v-invalid">Eliminate invalid phone numbers</a></li>
					<li><a href="#r4-2-v-inline">Find phone numbers in documents</a></li>
					<li><a href="#r4-2-v-leading1">Allow a leading &ldquo;1&rdquo;</a></li>
					<li><a href="#r4-2-v-local">Allow seven-digit phone numbers</a></li>
				</ul>
			</li>
		</ul>
	</li>
	<li><a href="#r4-3">Validate International Phone Numbers</a>
		<ul>
			<li>Variations:
				<ul>
					<li><a href="#r4-3-v-epp">Validate international phone numbers in EPP format</a></li>
				</ul>
			</li>
		</ul>
	</li>
</ul>


<div style="border:1px solid #999; background:#f3f3f3; padding:15px 15px 0; margin-bottom:25px;">
	<p>Following is an excerpt from <em><a href="http://www.amazon.com/dp/0596520689/?tag=slfb-20">Regular Expressions Cookbook</a></em> (O'Reilly, 2009) by Jan Goyvaerts and Steven Levithan. Reprinted with permission.</p>
</div>


<h3 id="r4-2">Validate and Format North American Phone Numbers</h3>

<h4 id="r4-2-p">Problem</h4>

<p>You want to determine whether a user entered a North American phone number in a common format, including the local area code. These formats include <code>1234567890</code>, <code>123-456-7890</code>, <code>123.456.7890</code>, <code>123 456 7890</code>, <code>(123) 456 7890</code>, and all related combinations. If the phone number is valid, you want to convert it to your standard format, <code>(123) 456-7890</code>, so that your phone number records are consistent.</p>

<h4 id="r4-2-s">Solution</h4>

<p>A regular expression can easily check whether a user entered something that looks like a valid phone number. By using capturing groups to remember each set of digits, the same regular expression can be used to replace the subject text with precisely the format you want.</p>

<h5 id="r4-2-s-regex">Regular expression</h5>

<div class="indent">
	<p><code>^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$</code><br />
	   <strong>Regex options:</strong> None<br />
	   <strong>Regex flavors:</strong> .NET, Java, JavaScript, PCRE, Perl, Python, Ruby</p>
</div>

<h5 id="r4-2-s-replacement">Replacement</h5>

<div class="indent">
	<p><code>($1) $2-$3</code><br />
	   <strong>Replacement text flavors:</strong> .NET, Java, JavaScript, Perl, PHP</p>

	<p><code>(\1) \2-\3</code><br />
	   <strong>Replacement text flavors:</strong> Python, Ruby</p>
</div>

<h5 id="r4-2-s-csharp">C#</h5>

<pre class="indent">Regex regexObj =
    new Regex(@"^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$");

if (regexObj.IsMatch(subjectString)) {
    string formattedPhoneNumber =
        regexObj.Replace(subjectString, "($1) $2-$3");
} else {
    // Invalid phone number
}</pre>

<h5 id="r4-2-s-js">JavaScript</h5>

<pre class="indent">var regexObj = /^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$/;

if (regexObj.test(subjectString)) {
    var formattedPhoneNumber =
        subjectString.replace(regexObj, "($1) $2-$3");
} else {
    // Invalid phone number
}</pre>

<h5 id="r4-2-s-other">Other programming languages</h5>

<p>See Recipes 3.5 and 3.15 for help implementing this regular expression with other programming languages.</p>

<h4 id="r4-2-d">Discussion</h4>

<p>This regular expression matches three groups of digits. The first group can optionally be enclosed with parentheses, and the first two groups can optionally be followed with a choice of three separators (a hyphen, dot, or space). The following layout breaks the regular expression into its individual parts, omitting the redundant groups of digits:</p>

<pre class="indent">^        # Assert position at the beginning of the string.
\(       # Match a literal "("...
  ?      #   between zero and one time.
(        # Capture the enclosed match to backreference 1...
  [0-9]  #   Match a digit...
    {3}  #     exactly three times.
)        # End capturing group 1.
\)       # Match a literal ")"...
  ?      #   between zero and one time.
[-. ]    # Match one character from the set "-. "...
  ?      #   between zero and one time.
&#x22ef;        # [Match the remaining digits and separator.]
$        # Assert position at the end of the string.</pre>

<p>Let&rsquo;s look at each of these parts more closely. The <code>^</code> and <code>$</code> at the beginning and end of the regular expression are a special kind of metacharacter called an <em>anchor</em> or <em>assertion</em>. Instead of matching text, assertions match a position within the text. Specifically, <code>^</code> matches at the beginning of the text, and <code>$</code> at the end. This ensures that the phone number regex does not match within longer text, such as <code>123-456-78901</code>.</p>

<p>As we&rsquo;ve repeatedly seen, parentheses are special characters in regular expressions, but in this case we want to allow a user to enter parentheses and have our regex recognize them. This is a textbook example of where we need a backslash to escape a special character so the regular expression treats it as literal input. Thus, the <code>\(</code> and <code>\)</code> sequences that enclose the first group of digits match literal parenthesis characters. Both are followed by a question mark, which makes them optional. We&rsquo;ll explain more about the question mark after discussing the other types of tokens in this regular expression.</p>

<p>The parentheses that appear without backslashes are capturing groups and are used to remember the values matched within them so that the matched text can be recalled later. In this case, backreferences to the captured values are used in the replacement text so we can easily reformat the phone number as needed.</p>

<p>Two other types of tokens used in this regular expression are character classes and quantifiers. Character classes allow you to match any one out of a set of characters. <code>[0-9]</code> is a character class that matches any digit. The regular expression flavors covered by this book all include the shorthand character class <code>\d</code> that also matches a digit, but in some flavors <code>\d</code> matches a digit from any language&rsquo;s character set or script, which is not what we want here. See Recipe 2.3 for more information about <code>\d</code>.</p>

<p><code>[-. ]</code> is another character class, one that allows any one of three separators. It&rsquo;s important that the hyphen appears first in this character class, because if it appeared
between other characters, it would create a range, as with <code>[0-9]</code>. Another way to ensure that a hyphen inside a character class matches a literal version of itself is to escape it with a backslash. <code>[.\- ]</code> is therefore equivalent.</p>

<p>Finally, quantifiers allow you to repeat a token or group. <code>{3}</code> is a quantifier that causes its preceding element to be repeated exactly three times. The regular expression <code>[0-9]{3}</code> is therefore equivalent to <code>[0-9][0-9][0-9]</code>, but is shorter and hopefully easier to read. A question mark (mentioned earlier) is a special quantifier that causes its preceding element to repeat zero or one time. It could also be written as <code>{0,1}</code>. Any quantifier that allows something to be repeated zero times effectively makes that element optional. Since a question mark is used after each separator, the phone number digits are allowed to run together.</p>

<p>Note that although this recipe claims to handle North American phone numbers, it&rsquo;s actually designed to work with <em>North American Numbering Plan</em> (NANP) numbers. The NANP is the telephone numbering plan for the countries that share the country code &ldquo;1&rdquo;. This includes the United States and its territories, Canada, Bermuda, and 16 Caribbean nations. It excludes Mexico and the Central American nations.</p>

<h4 id="r4-2-v">Variations</h4>

<h5 id="r4-2-v-invalid">Eliminate invalid phone numbers</h5>

<p>So far, the regular expression matches any 10-digit number. If you want to limit matches to valid phone numbers according to the North American Numbering Plan, here are the basic rules:</p>

<ul>
	<li><em>Area codes</em> start with a number from 2&ndash;9, followed by 0&ndash;8, and then any third digit.</li>
	<li>The second group of three digits, known as the <em>central office</em> or <em>exchange code</em>, starts with a number from 2&ndash;9, followed by any two digits.</li>
	<li>The final four digits, known as the <em>station code</em>, have no restrictions.</li>
</ul>

<p>These rules can easily be implemented with a few character classes:</p>

<div class="indent">
	<p><code>^\(?([2-9][0-8][0-9])\)?[-. ]?([2-9][0-9]{2})[-. ]?([0-9]{4})$</code><br />
	   <strong>Regex options:</strong> None<br />
	   <strong>Regex flavors:</strong> .NET, Java, JavaScript, PCRE, Perl, Python, Ruby</p>
</div>

<p>Beyond the basic rules just listed, there are a variety of reserved, unassigned, and restricted phone numbers. Unless you have very specific needs that require you to filter out as many phone numbers as possible, don&rsquo;t go overboard trying to eliminate unused numbers. New area codes that fit the rules listed earlier are made available regularly, and even if a phone number is valid, that doesn&rsquo;t necessarily mean it was issued or is in active use.</p>

<h5 id="r4-2-v-inline">Find phone numbers in documents</h5>

<p>Two simple changes allow the previous regular expression to match phone numbers within longer text:</p>

<div class="indent">
	<p><code>\(?\b([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})\b</code><br />
	   <strong>Regex options:</strong> None<br />
	   <strong>Regex flavors:</strong> .NET, Java, JavaScript, PCRE, Perl, Python, Ruby</p>
</div>

<p>Here, the <code>^</code> and <code>$</code> assertions that bound the regular expression to the beginning and end of the text have been removed. In their place, word boundary tokens (<code>\b</code>) have
been added to ensure that the matched text stands on its own and is not part of a longer number or word.</p>

<p>Similar to <code>^</code> and <code>$</code>, <code>\b</code> is an assertion that matches a position rather than any actual text. Specifically, <code>\b</code> matches the position between a word character and either a nonword character or the beginning or end of the text. Letters, numbers, and underscore are all considered word characters (see Recipe 2.6).</p>

<p>Note that the first word boundary token appears after the optional, opening parenthesis. This is important because there is no word boundary to be matched between two nonword characters, such as the opening parenthesis and a preceding space character. The first word boundary is relevant only when matching a number without parentheses, since the word boundary always matches between the opening parenthesis and the first digit of a phone number.</p>

<h5 id="r4-2-v-leading1">Allow a leading &ldquo;1&rdquo;</h5>

<p>You can allow an optional, leading &ldquo;1&rdquo; for the country code (which covers the North American Numbering Plan region) via the addition shown in the following regex:</p>

<div class="indent">
	<p><code>^(?:\+?1[-. ]?)?\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$</code><br />
	   <strong>Regex options:</strong> None<br />
	   <strong>Regex flavors:</strong> .NET, Java, JavaScript, PCRE, Perl, Python, Ruby</p>
</div>

<p>In addition to the phone number formats shown previously, this regular expression will also match strings such as <code>+1 (123) 456-7890</code> and <code>1-123-456-7890</code>. It uses a noncapturing group, written as <code>(?:&#x22ef;)</code>. When a question mark follows an unescaped left parenthesis like this, it&rsquo;s not a quantifier, but instead helps to identify the type of grouping. Standard capturing groups require the regular expression engine to keep track of backreferences, so it&rsquo;s more efficient to use noncapturing groups whenever the text matched by a group does not need to be referenced later. Another reason to use a noncapturing group here is to allow you to keep using the same replacement string as in the previous examples. If we added a capturing group, we&rsquo;d have to change <code>$1</code> to <code>$2</code> (and so on) in the replacement text shown earlier in this recipe.</p>

<p>The full addition to this version of the regex is <code>(?:\+?1[-. ]?)?</code>. The &ldquo;1&rdquo; in this pattern is preceded by an optional plus sign, and optionally followed by one of three separators (hyphen, dot, or space). The entire, added noncapturing group is also optional, but since the &ldquo;1&rdquo; is required within the group, the preceding plus sign and separator are not allowed if there is no leading &ldquo;1&rdquo;.</p>

<h5 id="r4-2-v-local">Allow seven-digit phone numbers</h5>

<p>To allow matching phone numbers that omit the local area code, enclose the first group of digits together with its surrounding parentheses and following separator in an optional, noncapturing group:</p>

<div class="indent">
	<p><code>^(?:\(?([0-9]{3})\)?[-. ]?)?([0-9]{3})[-. ]?([0-9]{4})$</code><br />
	   <strong>Regex options:</strong> None<br />
	   <strong>Regex flavors:</strong> .NET, Java, JavaScript, PCRE, Perl, Python, Ruby</p>
</div>

<p>Since the area code is no longer required as part of the match, simply replacing any match with <code>($1) $2-$3</code> might now result in something like <code>() 123-4567</code>, with an empty set of parentheses. To work around this, add code outside the regex that checks whether group 1 matched any text, and adjust the replacement text accordingly.</p>

<h4 id="r4-2-sa">See Also</h4>

<p><a href="#r4-3">Recipe 4.3</a> shows how to validate international phone numbers.</p>

<p>The North American Numbering Plan (NANP) is the telephone numbering plan for the United States and its territories, Canada, Bermuda, and 16 Caribbean nations. More information is available at <em><a href="http://www.nanpa.com">http://www.nanpa.com</a></em>.</p>


<hr />

<h3 id="r4-3">Validate International Phone Numbers</h3>

<h4 id="r4-3-p">Problem</h4>

<p>You want to validate international phone numbers. The numbers should start with a plus sign, followed by the country code and national number.</p>

<h4 id="r4-3-s">Solution</h4>

<h5 id="r4-3-s-regex">Regular expression</h5>

<div class="indent">
	<p><code>^\+(?:[0-9] ?){6,14}[0-9]$</code><br />
	   <strong>Regex options:</strong> None<br />
	   <strong>Regex flavors:</strong> .NET, Java, JavaScript, PCRE, Perl, Python, Ruby</p>
</div>

<h5 id="r4-3-s-js">JavaScript</h5>

<pre class="indent">function validate (phone) {
    var regex = /^\+(?:[0-9] ?){6,14}[0-9]$/;

    if (regex.test(phone)) {
        // Valid international phone number
    } else {
        // Invalid international phone number
    }
}</pre>

<h5 id="r4-3-s-other">Other programming languages</h5>

<p>See Recipe 3.5 for help implementing this regular expression with other programming languages.</p>

<h4 id="r4-3-d">Discussion</h4>

<p>The rules and conventions used to print international phone numbers vary significantly around the world, so it&rsquo;s hard to provide meaningful validation for an international phone number unless you adopt a strict format. Fortunately, there is a simple, industrystandard notation specified by ITU-T E.123. This notation requires that international phone numbers include a leading plus sign (known as the <em>international prefix symbol</em>), and allows only spaces to separate groups of digits. Although the tilde character (~) can appear within a phone number to indicate the existence of an additional dial tone, it has been excluded from this regular expression since it is merely a procedural element (in other words, it is not actually dialed) and is infrequently used. Thanks to the international phone numbering plan (ITU-T E.164), phone numbers cannot contain more than 15 digits. The shortest international phone numbers in use contain seven digits.</p>

<p>With all of this in mind, let&rsquo;s look at the regular expression again after breaking it into its pieces. Because this version is written using free-spacing style, the literal space character has been replaced with <code>\x20</code>:</p>

<pre class="indent">^         # Assert position at the beginning of the string.
\+        # Match a literal "+" character.
(?:       # Group but don't capture...
  [0-9]   #   Match a digit.
  \x20    #   Match a space character...
    ?     #     Between zero and one time.
)         # End the noncapturing group.
  {6,14}  #   Repeat the preceding group between 6 and 14 times.
[0-9]     # Match a digit.
$         # Assert position at the end of the string.</pre>
<div class="indent">
	<p><strong>Regex options:</strong> Free-spacing<br />
	   <strong>Regex flavors:</strong> .NET, Java, PCRE, Perl, Python, Ruby</p>
</div>

<p>The <code>^</code> and <code>$</code> anchors at the edges of the regular expression ensure that it matches the whole subject text. The noncapturing group&mdash;enclosed with <code>(?:&#x22ef;)</code>&mdash;matches a single digit, followed by an optional space character. Repeating this grouping with the interval quantifier <code>{6,14}</code> enforces the rules for the minimum and maximum number of digits, while allowing space separators to appear anywhere within the number. The second instance of the character class <code>[0-9]</code> completes the rule for the number of digits (bumping it up from between 6 and 14 digits to between 7 and 15), and ensures that the phone number does not end with a space.</p>

<h4 id="r4-3-v">Variations</h4>

<h5 id="r4-3-v-epp">Validate international phone numbers in EPP format</h5>

<div class="indent">
	<p><code>^\+[0-9]{1,3}\.[0-9]{4,14}(?:x.+)?$</code><br />
	   <strong>Regex options:</strong> None<br />
	   <strong>Regex flavors:</strong> .NET, Java, JavaScript, PCRE, Perl, Python, Ruby</p>
</div>

<p>This regular expression follows the international phone number notation specified by the Extensible Provisioning Protocol (EPP). EPP is a relatively recent protocol (finalized in 2004), designed for communication between domain name registries and registrars. It is used by a growing number of domain name registries, including <em>.com</em>, <em>.info</em>, <em>.net</em>, <em>.org</em>, and <em>.us</em>. The significance of this is that EPP-style international phone numbers are increasingly used and recognized, and therefore provide a good alternative format for storing (and validating) international phone numbers.</p>

<p>EPP-style phone numbers use the format <em>+CCC.NNNNNNNNNNxEEEE</em>, where <em>C</em> is the 1&ndash;3 digit country code, <em>N</em> is up to 14 digits, and <em>E</em> is the (optional) extension. The leading plus sign and the dot following the country code are required. The literal &ldquo;x&rdquo; character is required only if an extension is provided.</p>

<h4 id="r4-3-sa">See Also</h4>

<p><a href="#r4-2">Recipe 4.2</a> provides more options for validating North American phone numbers.</p>

<p>ITU-T Recommendation E.123 (&ldquo;Notation for national and international telephone numbers, e-mail addresses and Web addresses&rdquo;) can be downloaded here: <em><a href="http://www.itu.int/rec/T-REC-E.123">http://www.itu.int/rec/T-REC-E.123</a></em>.</p>

<p>ITU-T Recommendation E.164 (&ldquo;The international public telecommunication numbering plan&rdquo;) can be downloaded at <em><a href="http://www.itu.int/rec/T-REC-E.164">http://www.itu.int/rec/T-REC-E.164</a></em>.</p>

<p>National numbering plans can be downloaded at <em><a href="http://www.itu.int/ITU-T/inr/nnp">http://www.itu.int/ITU-T/inr/nnp</a></em>.</p>

<p>RFC 4933 defines the syntax and semantics of EPP contact identifiers, including international phone numbers. You can download RFC 4933 at <em><a href="http://tools.ietf.org/html/rfc4933">http://tools.ietf.org/html/rfc4933</a></em>.</p>

<div style="border:1px solid #999; background:#f3f3f3; padding:15px 15px 0; margin-bottom:25px;">
	<p>This has been an excerpt from <em><a href="http://www.amazon.com/dp/0596520689/?tag=slfb-20">Regular Expressions Cookbook</a></em> (O'Reilly, 2009) by Jan Goyvaerts and Steven Levithan. Reprinted with permission.</p>
</div><img src="http://feeds.feedburner.com/~r/badassery/~4/Wh5tdJOqG_8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.stevenlevithan.com/archives/validate-phone-number/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>‘High Performance JavaScript’ Giveaway Now Five Books</title>
		<link>http://blog.stevenlevithan.com/archives/hpjs-giveaway</link>
		<comments>http://blog.stevenlevithan.com/archives/hpjs-giveaway#comments</comments>
		<pubDate>Mon, 08 Feb 2010 17:10:35 +0000</pubDate>
		<dc:creator>Steven Levithan</dc:creator>
				<category><![CDATA[Books]]></category>
		<category><![CDATA[contest]]></category>
		<category><![CDATA[schwag]]></category>

		<guid isPermaLink="false">http://blog.stevenlevithan.com/?p=287</guid>
		<description><![CDATA[Laurel Ackerman, Director of Marketing for O'Reilly Media, was kind enough to offer to pick up the tab for my ongoing book giveaway and increase the booty to five books! If you haven't entered the contest yet (which ends February 24th), now's your chance because your odds of winning have just gone up.  ]]></description>
			<content:encoded><![CDATA[<p><a href="http://twitter.com/laurela">Laurel Ackerman</a>, Director of Marketing for O'Reilly Media, was kind enough to offer to pick up the tab for my ongoing <strong><a href="http://blog.stevenlevithan.com/archives/high-performance-javascript">book giveaway</a></strong> and increase the booty to five books! If you haven't entered the contest yet (which ends February 24<sup>th</sup>), now's your chance because your odds of winning have just gone up. <img src='http://blog.stevenlevithan.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p><img src="http://feeds.feedburner.com/~r/badassery/~4/WOb1TfVSsj8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.stevenlevithan.com/archives/hpjs-giveaway/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Flagrant Badassery Back Online</title>
		<link>http://blog.stevenlevithan.com/archives/back-online</link>
		<comments>http://blog.stevenlevithan.com/archives/back-online#comments</comments>
		<pubDate>Fri, 05 Feb 2010 06:54:49 +0000</pubDate>
		<dc:creator>Steven Levithan</dc:creator>
				<category><![CDATA[Yada Yada]]></category>

		<guid isPermaLink="false">http://blog.stevenlevithan.com/?p=267</guid>
		<description><![CDATA[

My blog has seen a lot of downtime over the last couple days; many people have reported seeing the message "Internal Server Error." I was in contact with my hosting provider from the beginning, and after several issues were fixed without the main problem going away, I moved this blog to a different server. Hopefully [...]]]></description>
			<content:encoded><![CDATA[<img src="http://blog.stevenlevithan.com/assets/images/error_500.gif" class="right" width="155" height="155" alt="Sign: 500 Internal Server Error" />

<p>My blog has seen a lot of downtime over the last couple days; many people have reported seeing the message "Internal Server Error." I was in contact with my hosting provider from the beginning, and after several issues were fixed without the main problem going away, I moved this blog to a different server. Hopefully that's the end of the trouble. For those of you who've been unable to enter the <a href="http://blog.stevenlevithan.com/archives/high-performance-javascript">book giveaway</a> for O'Reilly's <em>High Performance JavaScript</em> and <em>Regular Expressions Cookbook</em>, I apologize for all the hassle. Please <strong><a href="http://blog.stevenlevithan.com/archives/high-performance-javascript">try again</a></strong>!</p><img src="http://feeds.feedburner.com/~r/badassery/~4/dmGaJxYDBCo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.stevenlevithan.com/archives/back-online/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Five Free Copies of Upcoming O’Reilly Book ‘High Performance JavaScript’</title>
		<link>http://blog.stevenlevithan.com/archives/high-performance-javascript</link>
		<comments>http://blog.stevenlevithan.com/archives/high-performance-javascript#comments</comments>
		<pubDate>Wed, 03 Feb 2010 07:57:34 +0000</pubDate>
		<dc:creator>Steven Levithan</dc:creator>
				<category><![CDATA[Books]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Project Releases]]></category>
		<category><![CDATA[Regular Expressions]]></category>
		<category><![CDATA[contest]]></category>
		<category><![CDATA[regex performance]]></category>
		<category><![CDATA[schwag]]></category>

		<guid isPermaLink="false">http://blog.stevenlevithan.com/?p=243</guid>
		<description><![CDATA[

Last year, Yahoo! engineer and all-around JavaScript badass Nicholas Zakas asked if I was interested in writing a chapter for a new book on JavaScript performance that he was working on. I agreed, and that book, High Performance JavaScript, is now available for preorder at Amazon and other fine book retailers.

In addition to the wide-ranging [...]]]></description>
			<content:encoded><![CDATA[<a href="http://www.amazon.com/dp/059680279X/?tag=slfb-20"><img class="right" src="http://covers.oreilly.com/images/9780596802806/cat.gif" alt="Book cover: High Performance JavaScript"></a>

<p>Last year, Yahoo! engineer and all-around JavaScript badass <a href="http://www.nczonline.net/">Nicholas Zakas</a> asked if I was interested in writing a chapter for a new book on JavaScript performance that he was working on. I agreed, and that book, <strong><em><a href="http://www.amazon.com/dp/059680279X/?tag=slfb-20">High Performance JavaScript</a></em></strong>, is now available for preorder at Amazon and other fine book retailers.</p>

<p>In addition to the wide-ranging content by Nicholas and a chapter on string and regular expression performance by yours truly, chapters were also contributed by an awesome lineup of JavaScript performance gurus: <a href="http://techfoolery.com/">Ross Harmes</a>, <a href="http://www.julienlecomte.net/blog/">Julien Lecomte</a>, <a href="http://www.phpied.com/">Stoyan Stefanov</a>, and Matt Sweeney. This book is unique in its laser-focus on optimizing the performance of your JavaScript applications, and covers many advanced topics in the process. The chapter on strings and regular expressions provides what I think is easily the most in-depth coverage of cross-browser JavaScript regex performance currently available.</p>

<p>Here's the list of chapters:</p>

<ol>
	<li>Loading and Execution</li>
	<li>Data Access</li>
	<li>DOM Scripting <em>(Stoyan Stefanov)</em></li>
	<li>Algorithms and Flow Control</li>
	<li>Strings and Regular Expressions <em>(Steven Levithan)</em></li>
	<li>Responsive Interfaces</li>
	<li>Ajax <em>(Ross Harmes)</em></li>
	<li>Programming Practices</li>
	<li>Build and Deployment <em>(Julien Lecomte)</em></li>
	<li>Tools <em>(Matt Sweeney)</em></li>
</ol>

<p>To celebrate the completion of this book, <del>I'm giving away three copies.</del> <ins>O'Reilly Media increased the offer to five books!</ins> All you need to do is comment on this post, and on February 24<sup>th</sup>, I'll pick five people to send a copy to as soon as it's released (Amazon says March 15<sup>th</sup>). If you prefer, I'd be happy to send you a copy of <em><a href="http://www.amazon.com/dp/0596520689/?tag=slfb-20">Regular Expressions Cookbook</a></em> instead (please note which book you want in your comment). Four winners will be chosen at random from the pool of unique commenters (I'll be tracking IPs), and the fifth based on the reason given for why you want a copy.</p>

<p>Make sure to include your email address in the comment form, since I'll need it to contact you if you're selected (your email address won't be used for any other purpose). Good luck, and congratulations to Nicholas Zakas and all the other authors on completing a fantastic new book!</p>

<p><em>Edit (2010-02-05): My blog has been offline more often than not for the first two days after posting this, and many people have reported that they were unable to post a comment. I apologize for the screw-up&mdash;my blog is now on a different server, and the problems should be resolved. Please try again!</em></p>

<p><em>Edit (2010-02-08): O'Reilly Media kindly offered to pick up the tab for this giveaway, and increased the winnings to five books!</em></p><img src="http://feeds.feedburner.com/~r/badassery/~4/BbEV0nAoAwY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.stevenlevithan.com/archives/high-performance-javascript/feed</wfw:commentRss>
		<slash:comments>181</slash:comments>
		</item>
		<item>
		<title>XRegExp 1.0</title>
		<link>http://blog.stevenlevithan.com/archives/xregexp-1-0</link>
		<comments>http://blog.stevenlevithan.com/archives/xregexp-1-0#comments</comments>
		<pubDate>Wed, 24 Jun 2009 02:29:28 +0000</pubDate>
		<dc:creator>Steven Levithan</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Project Releases]]></category>
		<category><![CDATA[Regular Expressions]]></category>

		<guid isPermaLink="false">http://blog.stevenlevithan.com/archives/xregexp-1-0</guid>
		<description><![CDATA[After stalling for nearly a year, I've finally released XRegExp 1.0, the next generation of my JavaScript regular expression library. Although it doesn't add support for lookbehind (as I've previously suggested) due to what would amount to significant inherent limitations, it fixes a couple bugs, corrects even more cross-browser regex inconsistencies, and adds a suite [...]]]></description>
			<content:encoded><![CDATA[<p>After stalling for nearly a year, I've finally released <a href="http://xregexp.com">XRegExp 1.0</a>, the next generation of my JavaScript regular expression library. Although it doesn't add support for lookbehind (as I've previously suggested) due to what would amount to significant inherent limitations, it fixes a couple bugs, corrects even more cross-browser regex inconsistencies, and adds a suite of new regular expression functions and methods that make writing regex-intensive JavaScript applications easier than ever. One of these new functions, <code>XRegExp.addToken</code>, fundamentally changes XRegExp's implementation and allows you to easily create your own XRegExp plugins.</p>

<p>Here's XRegExp's abbreviated feature list from the brand new <a href="http://xregexp.com"><strong>xregexp.com</strong></a> (which includes extensive documentation and code examples):</p>

<ul>
	<li>Adds <a href="http://xregexp.com/syntax/">new regex and replacement text syntax</a>, including comprehensive support for <a href="http://xregexp.com/syntax/#namedCapture">named capture</a>.</li>
	<li>Adds two <a href="http://xregexp.com/flags/">new regex flags</a>: <code>s</code>, to make <a href="http://xregexp.com/flags/#singleline">dot match all</a> characters (aka <em>singleline</em> mode), and <code>x</code>, for <a href="http://xregexp.com/flags/#extended">free-spacing</a> and comments (aka <em>extended</em> mode).</li>
	<li>Provides a suite of <a href="http://xregexp.com/api/">12 functions and methods</a> that make complex regex processing a breeze.</li>
	<li>Automagically fixes the most commonly encountered <a href="http://xregexp.com/cross_browser/">cross-browser inconsistencies</a> in regex behavior and syntax.</li>
	<li>Lets you easily <a href="http://xregexp.com/plugins/">create and use plugins</a> that add new syntax and flags to XRegExp's regular expression language.</li>
</ul>

<p>The full list of changes can be seen in the <a href="http://xregexp.com/history/">changelog</a>. Please let me know if you find any bugs or have any suggestions for the library. I'd also love to hear about projects or sites that are using XRegExp (I've got a few listed on the XRegExp homepage now).</p><img src="http://feeds.feedburner.com/~r/badassery/~4/ZLDMErFDEsg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.stevenlevithan.com/archives/xregexp-1-0/feed</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
	</channel>
</rss>
