Skip to content

Instantly share code, notes, and snippets.

@benmccallum
Created November 3, 2021 10:36
Show Gist options
  • Save benmccallum/e971c9571ae2f37e5f375ba492eef2f5 to your computer and use it in GitHub Desktop.
Save benmccallum/e971c9571ae2f37e5f375ba492eef2f5 to your computer and use it in GitHub Desktop.
Verify - ScrubMatches - regex replacement with incrementing id
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text.RegularExpressions;
namespace VerifyTests
{
public static class VerifySettingsExtensions
{
public static VerifySettings ScrubMatches(
this VerifySettings verifySettings,
Regex regex,
string replacementPrefix = "Val_")
{
var groupNames = regex.GetGroupNames();
const string beforeGroupName = "before";
var hasBeforeGroup = groupNames.Contains(beforeGroupName);
const string afterGroupName = "after";
var hasAfterGroup = groupNames.Contains(afterGroupName);
const string valGroupName = "val";
if (!groupNames.Contains(valGroupName))
{
throw new ArgumentException($"Regex must contain a capturing group named {valGroupName}", nameof(regex));
}
var foundValues = new List<string>();
Func<string, string> replacementFunc = val =>
{
var index = foundValues.IndexOf(val);
if (index < 0)
{
index = foundValues.Count;
foundValues.Add(val);
}
return replacementPrefix + (index + 1).ToString();
};
bool TryReplaceMatches(string value, [NotNullWhen(true)] out string? result)
{
result = value;
var matches = regex.Matches(result);
var groupedMatches = matches
.Cast<Match>()
.GroupBy(m =>
(hasBeforeGroup ? m.Groups[beforeGroupName].Value : string.Empty) +
m.Groups[valGroupName].Value +
(hasAfterGroup ? m.Groups[afterGroupName].Value : string.Empty));
foreach (var uniqueValueMatch in groupedMatches)
{
var match = uniqueValueMatch.First();
result = result.Replace(
uniqueValueMatch.Key,
match.Groups[beforeGroupName].Value +
replacementFunc(match.Groups[valGroupName].Value) +
match.Groups[afterGroupName].Value);
}
return groupedMatches.Any();
}
verifySettings.AddScrubber(builder =>
{
if (!TryReplaceMatches(builder.ToString(), out var result))
{
return;
}
builder.Clear();
builder.Append(result);
});
return verifySettings;
}
public static SettingsTask ScrubMatches(
this SettingsTask settingsTasks,
Regex regex,
string replacementPrefix = "Val_")
{
settingsTasks.CurrentSettings.ScrubMatches(regex, replacementPrefix);
return settingsTasks;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment