Don't use regular expressions.
The best solution is the simple one. There are only eleven possible inexact matches, so just enumerate them:
List<string> inexactMatches = new List<string> {
"otato", "ptato", "poato", "potto", "potao", "potat",
"optato", "ptoato", "poatto", "pottao", "potaot"};
...
bool hasInexactMatch = inexactMatches.Contains(whatever);
It took less than a minute to type those out; use the easy specific solution rather than trying to do some crazy regular expression that's going to take you hours to find and debug.
If you're going to insist on using a regular expression, here's one that works:
otato|ptato|poato|potto|potao|potat|optato|ptoato|poatto|pottao|potaot
Again: simpler is better.
Now, one might suppose that you want to solve this problem for more words than "potato". In that case, you might have said so -- but regardless, we can come up with some easy solutions.
First, let's enumerate all the strings that have an omission of one letter from a target string. Strings are IEnumerable<char>
so let's solve the general problem:
static IEnumerable<T> OmitAt<T>(this IEnumerable<T> items, int i) =>
items.Take(i).Concat(items.Skip(i + 1));
That's a bit gross enumerating the sequence twice but I'm not going to stress about it. Now let's make a specific version for strings:
static IEnumerable<string> Omits(this string s) =>
Enumerable
.Range(0, s.Length)
.Select(i => new string(s.OmitAt(i).ToArray()));
Great. Now we can say "frob".Omits()
and get back rob, fob, frb, fro
.
Now let's do the swaps. Again, solve the general problem first:
static void Swap<T>(ref T x, ref T y)
{
T t = x;
x = y;
y = t;
}
static T[] SwapAt<T>(this IEnumerable<T> items, int i)
{
T[] newItems = items.ToArray();
Swap(ref newItems[i], ref newItems[i + 1]);
return newItems;
}
And now we can solve it for strings:
static IEnumerable<string> Swaps(this string s) =>
Enumerable
.Range(0, s.Length - 1)
.Select(i => new string(s.SwapAt(i)));
And now we're done:
string source = "potato";
string target = whatever;
bool match =
source.Swaps().Contains(target) ||
source.Omits().Contains(target);
Easy peasy. Solve general problems using simple, straightforward, correct algorithms that can be composed into larger solutions. None of my algorithms there was more than three lines long and they can easily be seen to be correct.