My fellow blogger Ted Kreuger posted this powershell thing where he wants to remove the NOLOCk keyword from a statement (I have no idea why but he must have a good reason). So I commented that he could perhaps have done it with linq instead of regex. I was mistaken linq has nothing to do with this.
Regex is evil.
So I set up a testcase, I didn’t feel like doing it in but in csharp, just for fun.
First an interface.
csharp
namespace NoLock
{
public interface INoLock
{
string FindAndReplaceNoLock(string noLock);
}
}
Then some tests for the regex.
```csharp using NUnit.Framework;
namespace NoLock { /// <summary> /// TestNoLockLinq /// </summary> /// <remarks> </remarks> [TestFixture] public class TestNoLockRegex { /// <summary> /// IfFindAndReplaceNoLockReturnsWithoutNoLockWhenNoLockIsHidinginWithInTheBeginning /// </summary> [Test] public void IfFindAndReplaceNoLockReturnsWithoutNoLockWhenNoLockIsHidinginWithInTheBeginning() { var nolock = new NoLockRegEx(); Assert.AreEqual(“SELECT * FROM HumanResources.Department WITH (INDEX(AK_Department_Name))“, nolock.FindAndReplaceNoLock( “SELECT * FROM HumanResources.Department WITH (NOLOCK,INDEX(AK_Department_Name))“)); }
/// <summary>
/// IfFindAndReplaceNoLockReturnsWithoutNoLockWhenNoLockIsHidinginWithAtTheEnd
/// </summary>
[Test]
public void IfFindAndReplaceNoLockReturnsWithoutNoLockWhenNoLockIsHidinginWithAtTheEnd()
{
var nolock = new NoLockRegEx();
Assert.AreEqual("SELECT * FROM HumanResources.Department WITH (INDEX(AK_Department_Name))",
nolock.FindAndReplaceNoLock(
"SELECT * FROM HumanResources.Department WITH (INDEX(AK_Department_Name),NOLOCK)"));
}
/// <summary>
/// IfFindAndReplaceNoLockReturnsWithoutNoLockWhenNoLockIsHidinginWithAlone
/// </summary>
[Test]
public void IfFindAndReplaceNoLockReturnsWithoutNoLockWhenNoLockIsHidinginWithAlone()
{
var nolock = new NoLockRegEx();
Assert.AreEqual("SELECT * FROM HumanResources.Department",
nolock.FindAndReplaceNoLock(
"SELECT * FROM HumanResources.Department WITH (NOLOCK)"));
}
/// <summary>
/// IfFindAndReplaceNoLockReturnsWithoutNoLockWhenNoLockIsAtTheEndNoParenthesis
/// </summary>
[Test]
public void IfFindAndReplaceNoLockReturnsWithoutNoLockWhenNoLockIsAtTheEndNoParenthesis()
{
var nolock = new NoLockRegEx();
Assert.AreEqual("SELECT * FROM HumanResources.Department",
nolock.FindAndReplaceNoLock(
"SELECT * FROM HumanResources.Department NOLOCK"));
}
/// <summary>
/// IfFindAndReplaceNoLockReturnsWithoutNoLockWhenNoLockIsAtTheEndWithParenthesis
/// </summary>
[Test]
public void IfFindAndReplaceNoLockReturnsWithoutNoLockWhenNoLockIsAtTheEndWithParenthesis()
{
var nolock = new NoLockRegEx();
Assert.AreEqual("SELECT * FROM HumanResources.Department",
nolock.FindAndReplaceNoLock(
"SELECT * FROM HumanResources.Department (NOLOCK)"));
}
}
}``` All red.
then Teds implementation.
```csharp using System; using System.Text.RegularExpressions;
namespace NoLock { public class NoLockRegEx: INoLock { public string FindAndReplaceNoLock(string noLock) { if (Regex.IsMatch(noLock, “((({0,1}NOLOCK\,)|(\,NOLOCK({0,1}))“, RegexOptions.IgnoreCase)) { var replace = Regex.Replace(noLock, “((NOLOCK\,)|(\,NOLOCK({0,1}))“, “”); return replace.Trim(); } else if(Regex.IsMatch(noLock, “(WITH\s(({0,1}NOLOCK){0,1})|({0,1}NOLOCK){0,1})“, RegexOptions.IgnoreCase)) { var replace = Regex.Replace(noLock, “(WITH\s(({0,1}NOLOCK){0,1})|({0,1}NOLOCK){0,1})“, “”); return replace.Trim(); } return “”; } } }``` All green.
Then tests for the alternativee version.
```csharp using NUnit.Framework;
namespace NoLock { /// <summary> /// TestNoLockLinq /// </summary> /// <remarks> </remarks> [TestFixture] public class TestNoLockAlt {
/// <summary>
/// IfFindAndReplaceNoLockReturnsWithoutNoLockWhenNoLockIsHidinginWithInTheBeginning
/// </summary>
[Test]
public void IfFindAndReplaceNoLockReturnsWithoutNoLockWhenNoLockIsHidinginWithInTheBeginning()
{
var nolock = new NoLockAlt();
Assert.AreEqual("SELECT * FROM HumanResources.Department WITH (INDEX(AK_Department_Name))",
nolock.FindAndReplaceNoLock(
"SELECT * FROM HumanResources.Department WITH (NOLOCK,INDEX(AK_Department_Name))"));
}
/// <summary>
/// IfFindAndReplaceNoLockReturnsWithoutNoLockWhenNoLockIsHidinginWithAtTheEnd
/// </summary>
[Test]
public void IfFindAndReplaceNoLockReturnsWithoutNoLockWhenNoLockIsHidinginWithAtTheEnd()
{
var nolock = new NoLockAlt();
Assert.AreEqual("SELECT * FROM HumanResources.Department WITH (INDEX(AK_Department_Name))",
nolock.FindAndReplaceNoLock(
"SELECT * FROM HumanResources.Department WITH (INDEX(AK_Department_Name),NOLOCK)"));
}
/// <summary>
/// IfFindAndReplaceNoLockReturnsWithoutNoLockWhenNoLockIsHidinginWithAlone
/// </summary>
[Test]
public void IfFindAndReplaceNoLockReturnsWithoutNoLockWhenNoLockIsHidinginWithAlone()
{
var nolock = new NoLockAlt();
Assert.AreEqual("SELECT * FROM HumanResources.Department",
nolock.FindAndReplaceNoLock(
"SELECT * FROM HumanResources.Department WITH (NOLOCK)"));
}
/// <summary>
/// IfFindAndReplaceNoLockReturnsWithoutNoLockWhenNoLockIsAtTheEndNoParenthesis
/// </summary>
[Test]
public void IfFindAndReplaceNoLockReturnsWithoutNoLockWhenNoLockIsAtTheEndNoParenthesis()
{
var nolock = new NoLockAlt();
Assert.AreEqual("SELECT * FROM HumanResources.Department",
nolock.FindAndReplaceNoLock(
"SELECT * FROM HumanResources.Department NOLOCK"));
}
/// <summary>
/// IfFindAndReplaceNoLockReturnsWithoutNoLockWhenNoLockIsAtTheEndWithParenthesis
/// </summary>
[Test]
public void IfFindAndReplaceNoLockReturnsWithoutNoLockWhenNoLockIsAtTheEndWithParenthesis()
{
var nolock = new NoLockAlt();
Assert.AreEqual("SELECT * FROM HumanResources.Department",
nolock.FindAndReplaceNoLock(
"SELECT * FROM HumanResources.Department (NOLOCK)"));
}
}
}``` Hey, those look familiar.
All red.
And then the implementation.
```csharp using System; using System.Collections.Generic; using System.Linq;
namespace NoLock { public class NoLockAlt: INoLock { public string FindAndReplaceNoLock(string noLock) { var noLockList2 = new List<Tuple<string,string>>() { new Tuple<string,string>(“WITH (NOLOCK,”,“WITH (”), new Tuple<string,string>(“,NOLOCK)”,“)”)}; foreach (var n in noLockList2.Where(n => noLock.Contains(n.Item1))) { return noLock.Replace(n.Item1, n.Item2).Trim(); } var noLockList1 = new List<String> {“WITH NOLOCK”, “WITH (NOLOCK)”, “(NOLOCK)”, “NOLOCK”}; foreach (var n in noLockList1.Where(noLock.Contains)) { return noLock.Replace(n, “”).Trim(); } return noLock; } } }``` Yep these are the little things I do to keep myself busy.