private void TokenizeTest(string format, params string[] expectedTokens) { var actualTokens = new FormatStringTokenizer().Tokenize(format); if (expectedTokens.IsNullOrEmpty()) { actualTokens.Count.ShouldBe(0); return; } actualTokens.Count.ShouldBe(expectedTokens.Length); for (var i = 0; i < actualTokens.Count; i++) { var actualToken = actualTokens[i]; var expectedToken = expectedTokens[i]; actualToken.Text.ShouldBe(expectedToken.Trim('{', '}')); if (expectedToken.StartsWith("{") && expectedToken.EndsWith("}")) { actualToken.Type.ShouldBe(FormatStringTokenType.DynamicValue); } else { actualToken.Type.ShouldBe(FormatStringTokenType.ConstantText); } } }
/// <summary> /// Extracts dynamic values from a formatted string. /// </summary> /// <param name="str">String including dynamic values</param> /// <param name="format">Format of the string</param> /// <param name="ignoreCase">True, to search case-insensitive.</param> public static ExtractionResult Extract(string str, string format, bool ignoreCase = false) { var stringComparison = ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal; if (str == format) { return(new ExtractionResult(true)); } var formatTokens = new FormatStringTokenizer().Tokenize(format); if (formatTokens.IsNullOrEmpty()) { return(new ExtractionResult(str == "")); } var result = new ExtractionResult(true); for (var i = 0; i < formatTokens.Count; i++) { var currentToken = formatTokens[i]; var previousToken = i > 0 ? formatTokens[i - 1] : null; if (currentToken.Type == FormatStringTokenType.ConstantText) { if (i == 0) { if (!str.StartsWith(currentToken.Text, stringComparison)) { result.IsMatch = false; return(result); } str = str.Substring(currentToken.Text.Length); } else { var matchIndex = str.IndexOf(currentToken.Text, stringComparison); if (matchIndex < 0) { result.IsMatch = false; return(result); } Debug.Assert(previousToken != null, "previousToken can not be null since i > 0 here"); result.Matches.Add(new NameValue(previousToken.Text, str.Substring(0, matchIndex))); str = str.Substring(matchIndex + currentToken.Text.Length); } } } var lastToken = formatTokens.Last(); if (lastToken.Type == FormatStringTokenType.DynamicValue) { result.Matches.Add(new NameValue(lastToken.Text, str)); } return(result); }