using System.Text.RegularExpressions;
public static void Main()
"Credit Card 123456 7890 123456",
"Text 1234 5678 9012 3456 Text",
"Something 123 456 789 012 3456",
"Not a card (too long): 12345689123456789123",
var report = string.Join(Environment.NewLine, tests
.Select(test => $"{test,45} => {MaskCreditCardNumber(test)}"));
Console.WriteLine(report);
Console.WriteLine("123456789012345".MaskCreditCardNumber());
private static string MaskCreditCardNumber(string text)
if (string.IsNullOrEmpty(text))
return Regex.Replace(text, "[0-9][0-9 ]{13,}[0-9]", match =>
string digits = string.Concat(match.Value.Where(char.IsDigit));
return digits.Length == 16 || digits.Length == 15
? new string('X', digits.Length - 4) + digits[^4..]
public static class Extensions
public static string MaskCreditCardNumber(this string sender, char maskCharacter = 'X')
if (string.IsNullOrEmpty(sender))
return Regex.Replace(sender, "[0-9][0-9 ]{13,}[0-9]", match =>
string digits = string.Concat(match.Value.Where(char.IsDigit));
return digits.Length is 16 or 15
? new string(maskCharacter, digits.Length - 4) + digits[^4..]