title: In a regular expression, is (\W|$) a workable alternative for \b?
body: <p>We have a client application where the users want to search "notes" fields for specified text.   The fields are either formatted with HTML or plaintext.  One of the recent changes that we made was to only support "whole word" matches.  Using <code>\b</code>, we made this happen.  Pattern:</p>
  
  <pre><code>"\b(?:match)\b" &lt;-- works
  </code></pre>
  
  <p>New day, new problem:  one of the values that they want to find is a number followed by a percent sign.  (<code>%</code>)  However, the pattern doesn't match.  After some research, I was able to determine that, for a character at position <em>n</em> to be considered an end-of-word boundary, <code>\b</code> asserts that the character at position <em>n - 1</em> must be a word character.  However, <code>%</code> is not a word character, so the match fails.</p>
  
  <pre><code>"\b(?:7.0%)\b" &lt;-- fails
  </code></pre>
  
  <p>I changed this to match <code>\W</code>, and it works, but this has the drawback that there must always be another character following the matched pattern.</p>
  
  <pre><code>"\b(?:7.0%)\W" &lt;-- works, mostly
  </code></pre>
  
  <p>So what I want to know is, can I use the following as a pattern and have it match end-of-string matches?</p>
  
  <pre><code>"\b(?:7.0%)(\W|$)" &lt;-- ??
  </code></pre>
  
  <p>I tested it and it <em>appears</em> to work, but is there anything that is going to bite me down the road?</p>
  
  <p><em>Edit:</em></p>
  
  <p>Here's a quick test harness that demonstrates the different behaviors, including the answer from agent-j:</p>
  
  <pre class="lang-cs prettyprint-override"><code>List&lt;string&gt; testInputs = new List&lt;string&gt;();
  
  testInputs.Add("This string contains 7.0% embedded within it.");
  testInputs.Add("In this string, 7.0%\nis at the end of a line.");
  testInputs.Add("7.0% starts this string.");
  testInputs.Add("This string ends with 7.0%");
  
  List&lt;string&gt; testPatterns = new List&lt;string&gt;();
  testPatterns.Add(@"\b(?:7.0%)\b");
  testPatterns.Add(@"\b(?:7.0%)\W");
  testPatterns.Add(@"\b(?:7.0%)(\W|$)");
  testPatterns.Add(@"\b(?:7.0%)(?!\w)");
  
  foreach (var patt in testPatterns)
  {
      Console.WriteLine(string.Format("Testing pattern '{0}'", patt));
  
      foreach (var input in testInputs)
      {
          Console.WriteLine(string.Format("Input '{0}'; result: {1}", input, Regex.IsMatch(input, patt)));
      }
  
      Console.WriteLine();
  }
  </code></pre>
  
  <p>Output: </p>
  
  <pre><code>Testing pattern '\b(?:7.0%)\b'
  Input 'This string contains 7.0% embedded within it.'; result: False
  Input 'In this string, 7.0%
  is at the end of a line.'; result: False
  Input '7.0% starts this string.'; result: False
  Input 'This string ends with 7.0%'; result: False
  
  Testing pattern '\b(?:7.0%)\W'
  Input 'This string contains 7.0% embedded within it.'; result: True
  Input 'In this string, 7.0%
  is at the end of a line.'; result: True
  Input '7.0% starts this string.'; result: True
  Input 'This string ends with 7.0%'; result: False
  
  Testing pattern '\b(?:7.0%)(\W|$)'
  Input 'This string contains 7.0% embedded within it.'; result: True
  Input 'In this string, 7.0%
  is at the end of a line.'; result: True
  Input '7.0% starts this string.'; result: True
  Input 'This string ends with 7.0%'; result: True
  
  Testing pattern '\b(?:7.0%)(?!\w)'
  Input 'This string contains 7.0% embedded within it.'; result: True
  Input 'In this string, 7.0%
  is at the end of a line.'; result: True
  Input '7.0% starts this string.'; result: True
  Input 'This string ends with 7.0%'; result: True
  </code></pre>