<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8"/>
    <title>Tutorial: F# Verbal Expressions
</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <meta name="description" content="Composable F# regular expressions."/>
    <meta name="author" content="Jack Fox"/>

    <script src="https://code.jquery.com/jquery-1.8.0.js"></script>
    <script src="https://code.jquery.com/ui/1.8.23/jquery-ui.js"></script>
    <script src="https://netdna.bootstrapcdn.com/twitter-bootstrap/2.2.1/js/bootstrap.min.js"></script>
    <link href="https://netdna.bootstrapcdn.com/twitter-bootstrap/2.2.1/css/bootstrap-combined.min.css" rel="stylesheet"/>

    <link type="text/css" rel="stylesheet" href="/FsRegEx/content/style.css" />
    <script type="text/javascript" src="/FsRegEx/content/tips.js"></script>
    <!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
    <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
    <![endif]-->
  </head>
  <body>
    <div class="container">
      <div class="masthead">
        <ul class="nav nav-pills pull-right">
          <li><a href="http://fsharp.org">fsharp.org</a></li>
          <li><a href="https://github.com/jackfoxy/FsRegEx">github page</a></li>
        </ul>
        <h3 class="muted"><a href="/FsRegEx/index.html">FsRegEx</a></h3>
      </div>
      <hr />
      <div class="row">
        <div class="span9" id="main">
          
<h1><a name="Tutorial-F-Verbal-Expressions" class="anchor" href="#Tutorial-F-Verbal-Expressions">Tutorial: F# Verbal Expressions</a></h1>
<p>The <code>VerbalExpressions</code> module includes the <code>FsRegEx</code> type which wraps the familiar .NET <code>RegEx</code> in a type with useful functional members.
Multiple constructors start with a regular expression in the constructor.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs1', 1)" onmouseover="showTip(event, 'fs1', 1)" class="id">fsRegEx</span> <span class="o">=</span> <span class="k">new</span> <span class="id">FsRegEx</span><span class="pn">(</span><span class="s">@&quot;[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}&quot;</span><span class="pn">)</span>
</code></pre></td>
</tr>
</table>
<p>This the module is an experimental DSL that allows you to compose regular expressions in natural language
using the immutable <code>FsRegEx</code> type. The remainder of this tutorial is concerned with the experimental DSL which is, frankly, not that practical.</p>
<p>For practical examples of using the core <code>FsRegEx</code> module for composability, see the following examples:</p>
<ul>
<li><p><a href="matching.html">Matching</a></p></li>
<li><p><a href="group.html">Matching Groups</a></p></li>
<li><p><a href="replacesplit.html">Replace and Split</a></p></li>
<li><p><a href="capture.html">Capture</a></p></li>
</ul>
<h2><a name="Verbal-Expressions-DSL" class="anchor" href="#Verbal-Expressions-DSL">Verbal Expressions DSL</a></h2>
<p>You can compose values of the FsRegEx type with the |&gt; operator, including creating a new regular expression by logical or on 2 existing FsRegExs.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l"> 1: </span>
<span class="l"> 2: </span>
<span class="l"> 3: </span>
<span class="l"> 4: </span>
<span class="l"> 5: </span>
<span class="l"> 6: </span>
<span class="l"> 7: </span>
<span class="l"> 8: </span>
<span class="l"> 9: </span>
<span class="l">10: </span>
<span class="l">11: </span>
<span class="l">12: </span>
<span class="l">13: </span>
<span class="l">14: </span>
<span class="l">15: </span>
<span class="l">16: </span>
<span class="l">17: </span>
<span class="l">18: </span>
<span class="l">19: </span>
<span class="l">20: </span>
<span class="l">21: </span>
<span class="l">22: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="pp">#r</span> <span class="s">&quot;FsRegEx.dll&quot;</span>
<span class="k">open</span> <span class="id">FsRegEx</span>
<span class="k">open</span> <span onmouseout="hideTip(event, 'fs2', 2)" onmouseover="showTip(event, 'fs2', 2)" class="id">System</span><span class="pn">.</span><span onmouseout="hideTip(event, 'fs3', 3)" onmouseover="showTip(event, 'fs3', 3)" class="id">Text</span><span class="pn">.</span><span onmouseout="hideTip(event, 'fs4', 4)" onmouseover="showTip(event, 'fs4', 4)" class="id">RegularExpressions</span>
<span class="k">open</span> <span class="id">VerbalExpressions</span>

<span class="k">let</span> <span onmouseout="hideTip(event, 'fs5', 5)" onmouseover="showTip(event, 'fs5', 5)" class="id">v</span> <span class="o">=</span>
    <span class="id">CommonFsRegEx</span><span class="pn">.</span><span class="id">Email</span>
    <span class="o">|&gt;</span> <span class="id">fsRegExOrFsRegEx</span> <span onmouseout="hideTip(event, 'fs6', 6)" onmouseover="showTip(event, 'fs6', 6)" class="id">RegexOptions</span><span class="pn">.</span><span onmouseout="hideTip(event, 'fs7', 7)" onmouseover="showTip(event, 'fs7', 7)" class="id">None</span> <span class="id">CommonFsRegEx</span><span class="pn">.</span><span class="id">Url</span>

<span class="k">let</span> <span onmouseout="hideTip(event, 'fs8', 8)" onmouseover="showTip(event, 'fs8', 8)" class="id">foundEmail</span> <span class="o">=</span>
    <span onmouseout="hideTip(event, 'fs5', 9)" onmouseover="showTip(event, 'fs5', 9)" class="id">v</span>
    <span class="o">|&gt;</span> <span class="id">isMatch</span> <span class="s">&quot;test@github.com&quot;</span>

<span class="k">let</span> <span onmouseout="hideTip(event, 'fs9', 10)" onmouseover="showTip(event, 'fs9', 10)" class="id">foundUrl</span> <span class="o">=</span>
    <span onmouseout="hideTip(event, 'fs5', 11)" onmouseover="showTip(event, 'fs5', 11)" class="id">v</span>
    <span class="o">|&gt;</span> <span class="id">isMatch</span> <span class="s">&quot;http://www.google.com&quot;</span>

<span onmouseout="hideTip(event, 'fs10', 12)" onmouseover="showTip(event, 'fs10', 12)" class="fn">printfn</span> <span class="s">&quot;</span><span class="pf">%b</span><span class="s">&quot;</span> <span onmouseout="hideTip(event, 'fs8', 13)" onmouseover="showTip(event, 'fs8', 13)" class="id">foundEmail</span>
<span onmouseout="hideTip(event, 'fs10', 14)" onmouseover="showTip(event, 'fs10', 14)" class="fn">printfn</span> <span class="s">&quot;</span><span class="pf">%b</span><span class="s">&quot;</span> <span onmouseout="hideTip(event, 'fs9', 15)" onmouseover="showTip(event, 'fs9', 15)" class="id">foundUrl</span>

<span class="c">// true</span>
<span class="c">// true</span>
</code></pre></td>
</tr>
</table>
<p>Natural language composition consists of building up a new FsRegEx from an old by functions which append special characters, groups, modifiers, and other attributes of the regular expression language.</p>
<p>function : 'T -&gt; FsRegEx -&gt; FsRegEx</p>
<p>See the API documentation for all the regular expression functions available.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l"> 1: </span>
<span class="l"> 2: </span>
<span class="l"> 3: </span>
<span class="l"> 4: </span>
<span class="l"> 5: </span>
<span class="l"> 6: </span>
<span class="l"> 7: </span>
<span class="l"> 8: </span>
<span class="l"> 9: </span>
<span class="l">10: </span>
<span class="l">11: </span>
<span class="l">12: </span>
<span class="l">13: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">open</span> <span class="id">VerbalExpressions</span>

<span class="k">let</span> <span onmouseout="hideTip(event, 'fs11', 16)" onmouseover="showTip(event, 'fs11', 16)" class="id">foundFromGithub</span> <span class="o">=</span>
    <span class="id">FsRegEx</span><span class="pn">(</span><span class="pn">)</span>
    <span class="o">|&gt;</span> <span class="id">startOfLine</span>
    <span class="o">|&gt;</span> <span class="id">something</span>
    <span class="o">|&gt;</span> <span class="id">then&#39;</span> <span class="s">&quot;github.com&quot;</span>
    <span class="o">|&gt;</span> <span class="id">endOfLine</span>
    <span class="o">|&gt;</span> <span class="id">isMatch</span> <span class="s">&quot;test@github.com&quot;</span>

<span onmouseout="hideTip(event, 'fs10', 17)" onmouseover="showTip(event, 'fs10', 17)" class="fn">printfn</span> <span class="s">&quot;</span><span class="pf">%b</span><span class="s">&quot;</span> <span onmouseout="hideTip(event, 'fs11', 18)" onmouseover="showTip(event, 'fs11', 18)" class="id">foundFromGithub</span>

<span class="c">// true</span>
</code></pre></td>
</tr>
</table>
<p>You do not have to worry about escaping special characters in your regular expression.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l"> 1: </span>
<span class="l"> 2: </span>
<span class="l"> 3: </span>
<span class="l"> 4: </span>
<span class="l"> 5: </span>
<span class="l"> 6: </span>
<span class="l"> 7: </span>
<span class="l"> 8: </span>
<span class="l"> 9: </span>
<span class="l">10: </span>
<span class="l">11: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs12', 19)" onmouseover="showTip(event, 'fs12', 19)" class="id">foundSomethingSpecial</span> <span class="o">=</span>
    <span class="id">FsRegEx</span><span class="pn">(</span><span class="pn">)</span>
    <span class="o">|&gt;</span> <span class="id">startOfLine</span>
    <span class="o">|&gt;</span> <span class="id">something</span>
    <span class="o">|&gt;</span> <span class="id">then&#39;</span> <span class="s">&quot;*+?&quot;</span>
    <span class="o">|&gt;</span> <span class="id">anything</span>
    <span class="o">|&gt;</span> <span class="id">isMatch</span> <span class="s">&quot;blah blah blah*+?yackety yack&quot;</span>

<span onmouseout="hideTip(event, 'fs10', 20)" onmouseover="showTip(event, 'fs10', 20)" class="fn">printfn</span> <span class="s">&quot;</span><span class="pf">%b</span><span class="s">&quot;</span> <span onmouseout="hideTip(event, 'fs12', 21)" onmouseover="showTip(event, 'fs12', 21)" class="id">foundSomethingSpecial</span>

<span class="c">// true</span>
</code></pre></td>
</tr>
</table>
<p>Sometimes you may need more power than the natural language provides, or you just need to include a snippet of native regular expression. The add function lets you do that.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
<span class="l">6: </span>
<span class="l">7: </span>
<span class="l">8: </span>
<span class="l">9: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs13', 22)" onmouseover="showTip(event, 'fs13', 22)" class="id">foundSpecialInMultiline</span> <span class="o">=</span>
    <span class="id">FsRegEx</span><span class="pn">(</span><span class="pn">)</span>
    <span class="o">|&gt;</span> <span class="id">add</span> <span class="s">@&quot;phrase1\*\+\?&quot;</span>
    <span class="o">|&gt;</span> <span class="id">anything</span>
    <span class="o">|&gt;</span> <span class="id">isMatch</span> <span class="s">@&quot;phrase1*+?RestOfLine\n&quot;</span>
    
<span onmouseout="hideTip(event, 'fs10', 23)" onmouseover="showTip(event, 'fs10', 23)" class="fn">printfn</span> <span class="s">&quot;</span><span class="pf">%b</span><span class="s">&quot;</span> <span onmouseout="hideTip(event, 'fs13', 24)" onmouseover="showTip(event, 'fs13', 24)" class="id">foundSpecialInMultiline</span>

<span class="c">// true</span>
</code></pre></td>
</tr>
</table>
<p>FsRegExs posses all the power of the .Net RegEx class in a composable form.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l"> 1: </span>
<span class="l"> 2: </span>
<span class="l"> 3: </span>
<span class="l"> 4: </span>
<span class="l"> 5: </span>
<span class="l"> 6: </span>
<span class="l"> 7: </span>
<span class="l"> 8: </span>
<span class="l"> 9: </span>
<span class="l">10: </span>
<span class="l">11: </span>
<span class="l">12: </span>
<span class="l">13: </span>
<span class="l">14: </span>
<span class="l">15: </span>
<span class="l">16: </span>
<span class="l">17: </span>
<span class="l">18: </span>
<span class="l">19: </span>
<span class="l">20: </span>
<span class="l">21: </span>
<span class="l">22: </span>
<span class="l">23: </span>
<span class="l">24: </span>
<span class="l">25: </span>
<span class="l">26: </span>
<span class="l">27: </span>
<span class="l">28: </span>
<span class="l">29: </span>
<span class="l">30: </span>
<span class="l">31: </span>
<span class="l">32: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs14', 25)" onmouseover="showTip(event, 'fs14', 25)" class="id">n</span> <span class="o">=</span>
    <span class="id">FsRegEx</span><span class="pn">(</span><span class="pn">)</span>
    <span class="o">|&gt;</span> <span class="id">word</span>
    <span class="o">|&gt;</span> <span class="id">matches</span> <span class="s">&quot;three words here&quot;</span>

<span onmouseout="hideTip(event, 'fs10', 26)" onmouseover="showTip(event, 'fs10', 26)" class="fn">printfn</span> <span class="s">&quot;</span><span class="pf">%i</span><span class="s">&quot;</span> <span onmouseout="hideTip(event, 'fs14', 27)" onmouseover="showTip(event, 'fs14', 27)" class="id">n</span><span class="pn">.</span><span class="id">Length</span>

<span class="c">// 3</span>

<span class="k">let</span> <span onmouseout="hideTip(event, 'fs15', 28)" onmouseover="showTip(event, 'fs15', 28)" class="id">betterFormat</span> <span class="o">=</span>
    <span class="id">FsRegEx</span><span class="pn">(</span><span class="pn">)</span>
    <span class="o">|&gt;</span> <span class="id">add</span> <span class="s">&quot;\s+&quot;</span>
    <span class="o">|&gt;</span> <span class="id">or&#39;</span> <span class="s">&quot;whitespace&quot;</span>
    <span class="o">|&gt;</span> <span class="id">replace</span> <span class="s">&quot;This     is   text with   far  too   much   whitespace&quot;</span> <span class="s">&quot; &quot;</span>

<span onmouseout="hideTip(event, 'fs10', 29)" onmouseover="showTip(event, 'fs10', 29)" class="fn">printfn</span> <span class="s">&quot;</span><span class="pf">%s</span><span class="s">&quot;</span> <span onmouseout="hideTip(event, 'fs15', 30)" onmouseover="showTip(event, 'fs15', 30)" class="id">betterFormat</span>

<span class="c">// This is text with far too much  </span>

<span class="k">let</span> <span onmouseout="hideTip(event, 'fs16', 31)" onmouseover="showTip(event, 'fs16', 31)" class="id">groupName</span> <span class="o">=</span>  <span class="s">&quot;GroupNumber&quot;</span>
 
<span class="id">FsRegEx</span><span class="pn">(</span><span class="pn">)</span>
<span class="o">|&gt;</span> <span class="id">add</span> <span class="s">&quot;COD&quot;</span>
<span class="o">|&gt;</span> <span class="id">beginCaptureNamed</span> <span onmouseout="hideTip(event, 'fs16', 32)" onmouseover="showTip(event, 'fs16', 32)" class="id">groupName</span>
<span class="o">|&gt;</span> <span class="id">any</span> <span class="s">&quot;0-9&quot;</span>
<span class="o">|&gt;</span> <span class="id">repeatPrevious</span> <span class="n">3</span>
<span class="o">|&gt;</span> <span class="id">endCapture</span>
<span class="o">|&gt;</span> <span class="id">then&#39;</span> <span class="s">&quot;END&quot;</span>
<span class="o">|&gt;</span> <span class="id">capture</span> <span class="s">&quot;COD123END&quot;</span> <span onmouseout="hideTip(event, 'fs16', 33)" onmouseover="showTip(event, 'fs16', 33)" class="id">groupName</span>
<span class="o">|&gt;</span> <span onmouseout="hideTip(event, 'fs10', 34)" onmouseover="showTip(event, 'fs10', 34)" class="fn">printfn</span> <span class="s">&quot;</span><span class="pf">%s</span><span class="s">&quot;</span>

<span class="c">// 123</span>
</code></pre></td>
</tr>
</table>
<p>FsRegEx comes with first class support for unicode, including unicode general categories and .Net extension blocks.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
<span class="l">6: </span>
<span class="l">7: </span>
<span class="l">8: </span>
<span class="l">9: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="id">FsRegEx</span><span class="pn">(</span><span class="pn">)</span>
<span class="o">|&gt;</span> <span class="id">beginCaptureNamed</span> <span class="s">&quot;upper&quot;</span>
<span class="o">|&gt;</span> <span class="id">unicodeCategory</span> <span class="id">Unicode</span><span class="pn">.</span><span class="id">UnicodeGeneralCategory</span><span class="pn">.</span><span class="id">LetterUppercase</span>
<span class="o">|&gt;</span> <span class="id">add</span> <span class="s">&quot;+&quot;</span>
<span class="o">|&gt;</span> <span class="id">endCapture</span>
<span class="o">|&gt;</span> <span class="id">capture</span> <span class="s">&quot;some mixed case WORDS&quot;</span> <span class="s">&quot;upper&quot;</span>
<span class="o">|&gt;</span> <span onmouseout="hideTip(event, 'fs10', 35)" onmouseover="showTip(event, 'fs10', 35)" class="fn">printfn</span> <span class="s">&quot;</span><span class="pf">%s</span><span class="s">&quot;</span>

<span class="c">// WORDS</span>
</code></pre></td>
</tr>
</table>

<div class="tip" id="fs1">val fsRegEx : obj</div>
<div class="tip" id="fs2">namespace System</div>
<div class="tip" id="fs3">namespace System.Text</div>
<div class="tip" id="fs4">namespace System.Text.RegularExpressions</div>
<div class="tip" id="fs5">val v : obj</div>
<div class="tip" id="fs6">type RegexOptions =<br />&#160;&#160;| None = 0<br />&#160;&#160;| IgnoreCase = 1<br />&#160;&#160;| Multiline = 2<br />&#160;&#160;| ExplicitCapture = 4<br />&#160;&#160;| Compiled = 8<br />&#160;&#160;| Singleline = 16<br />&#160;&#160;| IgnorePatternWhitespace = 32<br />&#160;&#160;| RightToLeft = 64<br />&#160;&#160;| ECMAScript = 256<br />&#160;&#160;| CultureInvariant = 512</div>
<div class="tip" id="fs7">field RegexOptions.None: RegexOptions = 0</div>
<div class="tip" id="fs8">val foundEmail : bool</div>
<div class="tip" id="fs9">val foundUrl : bool</div>
<div class="tip" id="fs10">val printfn : format:Printf.TextWriterFormat&lt;&#39;T&gt; -&gt; &#39;T</div>
<div class="tip" id="fs11">val foundFromGithub : bool</div>
<div class="tip" id="fs12">val foundSomethingSpecial : bool</div>
<div class="tip" id="fs13">val foundSpecialInMultiline : bool</div>
<div class="tip" id="fs14">val n : obj</div>
<div class="tip" id="fs15">val betterFormat : string</div>
<div class="tip" id="fs16">val groupName : string</div>

        </div>
        <div class="span3">
          <img src="/FsRegEx/img/logo.png" alt="F# Project" style="width:150px;margin:10px" />  
            <ul class="nav nav-list" id="menu" style="margin-top: 20px;">
                <li class="nav-header">FsRegEx</li>
                <li><a href="/FsRegEx/index.html">Home page</a></li>
                <li class="divider"></li>
                <li><a href="http://nuget.org/packages/FsRegEx">Get Library via NuGet</a></li>
                <li><a href="https://github.com/jackfoxy/FsRegEx">Source Code on GitHub</a></li>
                <li><a href="/FsRegEx/license.html">License</a></li>
                <li><a href="/FsRegEx/release-notes.html">Release Notes</a></li>

                <li class="nav-header">Examples</li>
                <li><a href="/FsRegEx/matching.html">Matching</a></li>
                <li><a href="/FsRegEx/group.html">Match Groups</a></li>
                <li><a href="/FsRegEx/replacesplit.html">Replace and Split</a></li>
                <li><a href="/FsRegEx/capture.html">Capture</a></li>

                <li class="nav-header">Documentation</li>
                <li><a href="/FsRegEx/reference/index.html">API Reference</a></li>

                <li class="nav-header">More...</li>
                <li><a href="/FsRegEx/emailregex.html">On the Futility of Email Regex Validation</a></li>
                <li><a href="/FsRegEx/tutorial.html">F# Verbal Expressions Tutorial</a></li>
            </ul>
        </div>
      </div>
    </div>
    <a href="https://github.com/jackfoxy/FsRegEx"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_right_gray_6d6d6d.png" alt="Fork me on GitHub"/></a>
  </body>
  </html>
