.NET Fiddle

CSharp · Console

/Program.cs

//@!nuget: FormatWith
//using FormatWith;
					
public class Program
{
	public static readonly System.Decimal PadTestValue = 1234.56M;
	public static readonly System.String LeftPadTestFormatString = "'{0,15:#,##0.00}'";
	public static readonly System.String RightPadTestFormatString = "'{0,-15:#,##0.00}'";
	public static readonly System.String LeftPadTestFormatWith = "'{PadTestValue,15:#,##0.00}'";
	public static readonly System.String RightPadTestFormatWith = "'{PadTestValue,-15:#,##0.00}'";
	public static readonly System.String LeftPadTestFormatOnly = "'{PadTestValue:#,##0.00}'";
	public static readonly System.String RightPadTestFormatOnly = "'{PadTestValue:#,##0.00}'";
	public static readonly System.String LeftPadTestAlignOnly = "'{PadTestValue,15}'";
	public static readonly System.String RightPadTestAlignOnly = "'{PadTestValue,-15}'";

	public static readonly System.Text.RegularExpressions.Regex parseRegEx = new System.Text.RegularExpressions.Regex(@"(?<token>([^,:\s]+))(,(?<alignment>-?\d+))?(:(?<format>.*))?", System.Text.RegularExpressions.RegexOptions.Compiled);
	
	public static readonly System.String ExpectedNumericValueLeftPad = "'       1,234.56'";
	public static readonly System.String ExpectedNumericValueRightPad = "'1,234.560      '";
	public static readonly System.String ExpectedTextValueLeftPad = "'        1234.56'";
	public static readonly System.String ExpectedTextValueRightPad = "'1234.56        '";
	public static void Main()
	{
		if(false)	// System.String.Format
		{
			System.Console.WriteLine("System.String.Format(...);");
			System.Console.WriteLine("--------------------------");
			System.Console.WriteLine(System.String.Format("'{0,15}'","Test"));
			System.Console.WriteLine(System.String.Format("'{0,-15}'","Test"));
			System.Console.WriteLine(System.String.Format(LeftPadTestFormatString, PadTestValue));
			System.Console.WriteLine(System.String.Format(RightPadTestFormatString, PadTestValue));
			System.Console.WriteLine();
		}
		
		if(false)	// String Interpolation Formatting
		{
			System.Console.WriteLine("String Interpolation");
			System.Console.WriteLine("--------------------");
			System.Console.WriteLine($"'{PadTestValue,15}'");
			System.Console.WriteLine($"'{PadTestValue,-15}'");
			System.Console.WriteLine($"'{PadTestValue,15:#,##0.00}'");
			System.Console.WriteLine($"'{PadTestValue,-15:#,##0.00}'");
			System.Console.WriteLine();
		}
		
		if(true)	// FormatWith Parse Fix
		{
			System.Console.WriteLine("FormatWith Parse Fix");
			System.Console.WriteLine("----------------------");
			System.Console.WriteLine(Parse("PadTestValue,15:#,##0.00"));
			System.Console.WriteLine(Parse("PadTestValue,-15:#,##0.00"));
			System.Console.WriteLine(Parse("PadTestValue:#,##0.00"));
			System.Console.WriteLine(Parse("PadTestValue:#,##0.00"));
			System.Console.WriteLine(Parse("PadTestValue,15"));
			System.Console.WriteLine(Parse("PadTestValue,-15"));

			System.DateTime startTime = System.DateTime.Now;
			for(System.Int32 i = 0; i < 10000; i++)
			{
				Parse("PadTestValue,15:#,##0.00");
			}
			System.TimeSpan span = System.DateTime.Now - startTime;
			System.Console.WriteLine($"Time: {span}");
			System.Console.WriteLine();
		}
		
		if(true)	// FormatWith Parse RegEx Fix
		{
			System.Console.WriteLine("FormatWith Parse RegEx Fix");
			System.Console.WriteLine("----------------------");
			System.Console.WriteLine(RegexParse("PadTestValue,15:#,##0.00"));
			System.Console.WriteLine(RegexParse("PadTestValue,-15:#,##0.00"));
			System.Console.WriteLine(RegexParse("PadTestValue:#,##0.00"));
			System.Console.WriteLine(RegexParse("PadTestValue:#,##0.00"));
			System.Console.WriteLine(RegexParse("PadTestValue,15"));
			System.Console.WriteLine(RegexParse("PadTestValue,-15"));

			System.DateTime startTime = System.DateTime.Now;
			for(System.Int32 i = 0; i < 10000; i++)
			{
				RegexParse("PadTestValue,15:#,##0.00");
			}
			System.TimeSpan span = System.DateTime.Now - startTime;
			System.Console.WriteLine($"Time: {span}");
			System.Console.WriteLine();
		}
		
		// FormatWith
		System.Collections.Generic.Dictionary<System.String, System.Decimal> replacementDictionary = new System.Collections.Generic.Dictionary<System.String, System.Decimal>()
		{
			{"PadTestValue", PadTestValue}
		};

		//System.Console.WriteLine("FormatWith");
		//System.Console.WriteLine("----------");
		//These all produce this error: 	Unhandled exception. System.Collections.Generic.KeyNotFoundException: The parameter "LeftPadTestValue,15:#,##.00" was not present in the lookup dictionary
		//System.Console.WriteLine(LeftPadTestFormatWith.FormattableWith(replacementDictionary));
		//System.Console.WriteLine(RightPadTestFormatWith.FormattableWith(replacementDictionary));
		//System.Console.WriteLine(LeftPadTestFormatWith.FormattableWith(replacementDictionary).ToString());
		//System.Console.WriteLine(RightPadTestFormatWith.FormattableWith(replacementDictionary).ToString());
		//System.Console.WriteLine(System.String.Format(LeftPadTestFormatWith.FormattableWith(replacementDictionary).ToString(), PadTestValue));
		//System.Console.WriteLine(System.String.Format(RightPadTestFormatWith.FormattableWith(replacementDictionary).ToString(), PadTestValue));
	}
	
	private static System.String Parse(System.String tokenKey)
	{
		string format = null;
		var separatorIdx = tokenKey.IndexOf(":", System.StringComparison.Ordinal);
		if (separatorIdx > -1)
		{
			format = tokenKey.Substring(separatorIdx + 1);
			tokenKey = tokenKey.Substring(0, separatorIdx);
		}
		/// Parse out alignment
		string alignment = null;
		var alignmentIdx = tokenKey.LastIndexOf(",", System.StringComparison.Ordinal);
		if(alignmentIdx > -1)
		{
			alignment = tokenKey.Substring(alignmentIdx + 1);
			tokenKey = tokenKey.Substring(0, alignmentIdx);
		}
		/// assemble full format string ([,ALIGNMENT][:FORMAT])
		string formatString = ((alignmentIdx > -1) ? $",{alignment}" : System.String.Empty) + ((separatorIdx > -1) ? $":{format}" : System.String.Empty);
		
		//System.Console.WriteLine($"Token Key: {tokenKey}");
		//System.Console.WriteLine($"Alignment: {alignment}");
		//System.Console.WriteLine($"Format: {format}");
		var fullFormatString = "{0" + formatString + "}";
		return(fullFormatString);
	}

	private static System.String RegexParse(System.String tokenKey)
	{
		System.Text.RegularExpressions.Match results = parseRegEx.Match(tokenKey);
		if(results.Success)
		{
			System.String token = results.Groups["token"].Value;
			System.String alignment = results.Groups["alignment"].Value;
			System.String format = results.Groups["format"].Value;
			
			//System.Console.WriteLine($"Token Key: {token}");
			//System.Console.WriteLine($"Alignment: {alignment} - {System.String.IsNullOrEmpty(alignment)}");
			//System.Console.WriteLine($"Format: {format} - {System.String.IsNullOrEmpty(format)}");

			/// assemble full format string ([,ALIGNMENT][:FORMAT])
			string formatString = ((!System.String.IsNullOrEmpty(alignment)) ? $",{alignment}" : System.String.Empty) + ((!System.String.IsNullOrEmpty(format)) ? $":{format}" : System.String.Empty);

			var fullFormatString = "{0" + formatString + "}";
			return(fullFormatString);
		}
		else
		{
			throw(new System.Exception($"Invalid token. '{tokenKey}'"));
		}
	}
	
}
;