private static void GenerateFromPattern(StringBuilder sb, string pattern, NamedPatterns namedPatterns = null, GenerationConfig config = null, Random random = null) { if (pattern == null || string.IsNullOrEmpty(pattern)) { throw new GenerationException("Argument 'pattern' cannot be null."); } if (namedPatterns == null) { namedPatterns = LoadDefaultNamedPatterns(config); } if (config != null && config.PatternFiles != null) { // Load all from the PatternFiles in config AppendPatternsFromConfigToCollection(config, namedPatterns); } if (config == null) { config = new GenerationConfig(); } if (random == null) { random = config.Random; } ProcessPattern(sb, pattern, namedPatterns, random); }
public static string GenerateFromPattern(string pattern, NamedPatterns namedPatterns, GenerationConfig config) { var sb = new StringBuilder(); InternalGenerateFromPattern(sb, pattern, namedPatterns, config, null); return(sb.ToString()); }
public static string GenerateFromPattern(string pattern, NamedPatterns namedPatterns = null, GenerationConfig config = null, Random random = null) { var sb = new StringBuilder(); GenerateFromPattern(sb, pattern, namedPatterns, config, random); return(sb.ToString()); }
private static void ProcessPattern(StringBuilder sb, string exp, NamedPatterns namedPatterns, Random random) { bool isEscaped = false; var curNdx = 0; while (curNdx < exp.Length) { var chx = exp[curNdx]; if (chx == _Escape) { if (isEscaped) { // "\\" handling isEscaped = false; } else { // "...\..." detected, entering escaped symbol handling on next pass. isEscaped = true; curNdx++; continue; } } if (!isEscaped && chx == _Section_Start) { AppendContentFromSectionExpression(sb, exp, ref curNdx, namedPatterns, random); continue; // skip to next character - index has already been forwarded to new position } // check are we entering a set pattern that may include a quantifier // Format = "[Vv]{4}" = generate 4 random ordered characters comprising of either V or v characters if (!isEscaped && chx == _Set_Start) { AppendContentFromSetExpression(sb, exp, ref curNdx, random); continue; // skip to next character - index has already been forwarded to new position } if (!isEscaped && chx == _NamedPattern_Start) { AppendContentFromNamedPattern(sb, exp, ref curNdx, namedPatterns, random); continue; } // check are we entering a repeat symbol section // Format = "L{4}" = repeat L symbol 4 times. // Format = "\\{4}" = repeat \ symbol 4 times. bool repeatSymbol = curNdx < exp.Length - 1 && exp[curNdx + 1] == _Quantifier_Start; if (repeatSymbol) { AppendRepeatedSymbol(sb, exp, ref curNdx, isEscaped, random); isEscaped = false; continue; // skip to next character - index has already been forwarded to new position } AppendCharacterDerivedFromSymbol(sb, chx, isEscaped, random); curNdx++; // increment to move to next character. isEscaped = false; } }
private static void GenerateFromAlternatedPattern(StringBuilder sb, NamedPatterns namedPatterns, string exp, ContentOptions contentOptions, Random random) { var alternates = exp.Split(_Alternation); for (int x = 0; x < contentOptions.Repeat; x++) { exp = alternates[random.Next(0, alternates.Length)]; GenerateFromPattern(sb, exp, namedPatterns, null, random); } }
public ValidityChain Match(NamedPatterns name) { Regex pattern = null; switch (name) { case NamedPatterns.Date: pattern = new Regex(@"^([01]?\d)\/([012]?\d|30|31)\/\d{1,4}$"); break; case NamedPatterns.Email: pattern = new Regex(@"^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$", RegexOptions.IgnoreCase); break; case NamedPatterns.Guid: pattern = new Regex(@"^(\{?([0-9a-fA-F]){8}-(([0-9a-fA-F]){4}-){3}([0-9a-fA-F]){12}\}?)$"); break; case NamedPatterns.Integer: pattern = new Regex(@"^\d+$"); break; case NamedPatterns.Number: pattern = new Regex(@"^[+-]?(\d+(\.\d*)?|\.\d+)([Ee]\d+)?$"); break; case NamedPatterns.Phone: pattern = new Regex(@"^[2-9]\d{2}-\d{3}-\d{4}$"); break; case NamedPatterns.Time12: pattern = new Regex(@"^[01]?\d:[0-5]\d?\s?[aApP]\.?[mM]\.?$"); break; case NamedPatterns.Time24: pattern = new Regex(@"^(20|21|22|23|[01]\d|\d)(([:][0-5]\d){1,2})$"); break; case NamedPatterns.URL: pattern = new Regex(@"^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$", RegexOptions.IgnoreCase); break; case NamedPatterns.USD: pattern = new Regex(@"^\$?(\d{1,3},?(\d{3},?)*\d{3}(\.\d{0,2})?|\d{1,3}(\.\d{0,2})?|\.\d{1,2}?)$"); break; case NamedPatterns.Zip: pattern = new Regex(@"^\d{5}(-\d{4})?$"); break; } return(Validate(s => pattern.IsMatch(s))); }
private static NamedPatterns LoadDefaultNamedPatterns() { var patterns = new NamedPatterns(); var path = FileReader.GetPatternFilePath("default"); if (File.Exists(path)) { patterns = FileReader.LoadNamedPatterns(path, false); } return(patterns); }
/// <summary> /// Takes in a string that contains 0 or more <<placeholder>> values and replaces the placeholder item with the expression it defines. /// </summary> /// <param name="template"></param> /// <param name="namedPatterns"></param> /// <returns></returns> public static string GenerateFromTemplate(string template, NamedPatterns namedPatterns) { var sb = new StringBuilder(); int index = 0; while (index < template.Length) { // Find our next placeholder int start = FindPositionOfNext(template, index, _Placeholder_Start, _Placeholder_End); if (start == -1) { sb.Append(template.Substring(index)); //add remaining string. break; // all done! } bool isEscaped = start > 2 && template[start - 1].Equals(_Escape) && template[start - 2].Equals(_Escape); if (isEscaped) { start = start - 2; } sb.Append(template.Substring(index, start - index)); // Append everything up to start as it is. if (isEscaped) { start = start + 2; } start = start + 2; // move past '<<' to start of expression int end = FindPositionOfNext(template, start, _Placeholder_End, _Placeholder_Start); // find end of placeholder if (end == -1) { throw new GenerationException("Unable to find closing placeholder after " + start); } var pattern = template.Substring(start, end - start); // grab our expression if (isEscaped) { sb.Append("<<" + pattern + ">>"); } else { sb.Append(GenerateFromPattern(pattern, namedPatterns)); // generate value from expression } index = end + 2; // update our index. } return(sb.ToString()); }
private static NamedPatterns LoadDefaultNamedPatterns(GenerationConfig generationConfig) { var patterns = new NamedPatterns(); if (generationConfig == null || generationConfig.LoadDefaultPatternFile == false) { return(patterns); // Dont attempt to load default pattern files with every execution -- too slow. } var path = FileReader.GetPatternFilePath("default"); if (File.Exists(path)) { patterns = FileReader.LoadNamedPatterns(path, false); } return(patterns); }
public void Can_Generate_NamedPatterns_All_Defaults_Name() { var sw = new System.Diagnostics.Stopwatch(); sw.Start(); var namedPatterns = FileReader.LoadNamedPatterns(@"default.tdg-patterns"); var nps = new NamedPatterns(); nps.CollectionName = "Test"; foreach (var dic in namedPatterns.Patterns) { var text = AlphaNumericGenerator.GenerateFromPattern("@" + dic.Name + "@"); Console.WriteLine("'{0}' produced '{1}'", dic.Name, text); Assert.IsTrue(text.Length > 0); } sw.Stop(); Console.WriteLine("All {0} default patterns generated in {1} milliseconds.\n" , namedPatterns.Patterns.Count , sw.ElapsedMilliseconds); }
private static void AppendContentFromNamedPattern(StringBuilder sb, string characters, ref int index, NamedPatterns namedPatterns, Random random) { var ndx = index; var tuple = GetContentOptions(characters, ref index, _NamedPattern_Start.ToString(CultureInfo.InvariantCulture), _NamedPattern_End.ToString(CultureInfo.InvariantCulture), random); if (namedPatterns.HasPattern(tuple.Content)) // $namedPattern; { GenerateFromPattern(sb, namedPatterns.GetPattern(tuple.Content).Pattern, namedPatterns, null, random); } else { var msg = BuildErrorSnippet(characters, ndx); msg = "Found named pattern placeholder '" + tuple.Content + "' but was not provided with a corresponding pattern Check Named Patterns file." + Environment.NewLine + msg; throw new GenerationException(msg); } }
/// <summary> /// /// </summary> /// <param name="pattern"> /// The format of the text produced. 15 random characters is the default. /// . - An uppercase or lowercase letter or number. /// w - Any Letter. /// L - An uppercase Letter. /// l - A lowercase letter. /// V - An uppercase Vowel. /// v - A lowercase vowel. /// C - An uppercase Consonant. /// c - A lowercase consonant. /// n - Any number, 1-9. /// d - Any number, 0-9. /// ------- /// Patterns can be produced: /// "\.{10}" will produce a random string 10 characters long. /// </param> /// <param name="namedPatterns"></param> /// <returns></returns> public static string GenerateFromPattern(string pattern, NamedPatterns namedPatterns) { if(pattern == null) throw new GenerationException("Argument 'pattern' cannot be null."); var sb = new StringBuilder(); bool isEscaped = false; int index = 0; while(index < pattern.Length) { char ch = pattern[index]; // check for escape chars for next part if (ch == _Escape) { if (isEscaped) { sb.Append(@"\"); isEscaped = false; index++; continue; } isEscaped = true; index++; continue; } // check are we entering a repeat pattern section that may include a quantifier // Format = "(LL){n,m}" = repeat xx pattern 4 times. if (!isEscaped && ch == _Section_Start) { AppendContentFromSectionExpression(sb, pattern, ref index, namedPatterns); continue; // skip to next character - index has already been forwarded to new position } // check are we entering a set pattern that may include a quantifier // Format = "[Vv]{4}" = generate 4 random ordered characters comprising of either V or v characters if (!isEscaped && ch == _Set_Start) { AppendContentFromSetExpression(sb, pattern, ref index); continue; // skip to next character - index has already been forwarded to new position } // check are we entering a repeat symbol section // Format = "L{4}" = repeat L symbol 4 times. bool repeatSymbol = index < pattern.Length -1 && pattern[index + 1] == _Quantifier_Start; if (repeatSymbol) { AppendRepeatedSymbol(sb, pattern, ref index, isEscaped); isEscaped = false; continue; // skip to next character - index has already been forwarded to new position } // check if we have encountered a named pattern. if (!isEscaped && ch == _NamedPattern_Start) { AppendContentFromNamedPattern(sb, pattern, ref index, namedPatterns); continue; } AppendCharacterDerivedFromSymbol(sb, ch, isEscaped); isEscaped = false; index++; } return sb.ToString(); }
/// <summary> /// Calculates the content from a repeated expression when the following form is enountered '[exp]{repeat}'. /// </summary> /// <param name="sb"></param> /// <param name="characters"></param> /// <param name="index"></param> /// <param name="namedPatterns"></param> private static void AppendContentFromSectionExpression(StringBuilder sb, string characters, ref int index, NamedPatterns namedPatterns) { var contentOptions = GetContentOptions(characters, ref index, _Section_Start, _Section_End); var exp = contentOptions.Content; if (contentOptions.ContainsAlternation) // containse alternations { GenerateFromAlternatedPattern(sb, namedPatterns, exp, contentOptions); return; } if (contentOptions.IsNegated) // containse alternations { GenerateFromNegatedSet(sb, contentOptions); return; } bool isEscaped = false; for (int x = 0; x < contentOptions.Repeat; x++) { var curNdx = 0; while (curNdx < exp.Length) { var chx = exp[curNdx]; if (chx == _Escape) { if (isEscaped) { isEscaped = false; sb.Append(chx); // append escaped character. curNdx++; continue; } isEscaped = true; curNdx++; continue; } if (!isEscaped && chx == _Section_Start) { AppendContentFromSectionExpression(sb, exp, ref curNdx, namedPatterns); continue; // skip to next character - index has already been forwarded to new position } // check are we entering a set pattern that may include a quantifier // Format = "[Vv]{4}" = generate 4 random ordered characters comprising of either V or v characters if (!isEscaped && chx == _Set_Start) { AppendContentFromSetExpression(sb, exp, ref curNdx); continue; // skip to next character - index has already been forwarded to new position } if (!isEscaped && chx == _NamedPattern_Start) { AppendContentFromNamedPattern(sb, exp, ref curNdx, namedPatterns); continue; } // check are we entering a repeat symbol section // Format = "L{4}" = repeat L symbol 4 times. bool repeatSymbol = curNdx < exp.Length - 1 && exp[curNdx + 1] == _Quantifier_Start; if (repeatSymbol) { AppendRepeatedSymbol(sb, exp, ref curNdx, isEscaped); isEscaped = false; continue; // skip to next character - index has already been forwarded to new position } AppendCharacterDerivedFromSymbol(sb, chx, isEscaped); curNdx++; // increment to move to next character. isEscaped = false; } } }
/// <summary> /// Calculates the content from a repeated expression when the following form is enountered '[exp]{repeat}'. /// </summary> /// <param name="sb"></param> /// <param name="characters"></param> /// <param name="index"></param> /// <param name="namedPatterns"></param> private static void AppendContentFromSectionExpression(StringBuilder sb, string characters, ref int index, NamedPatterns namedPatterns) { var contentOptions = GetContentOptions(characters, ref index, _Section_Start, _Section_End); var exp = contentOptions.Content; if (contentOptions.ContainsAlternation) // containse alternations { GenerateFromAlternatedPattern(sb, namedPatterns, exp, contentOptions); return; } if (contentOptions.IsNegated) // containse alternations { GenerateFromNegatedSet(sb, contentOptions); return; } bool isEscaped = false; for (int x = 0; x < contentOptions.Repeat; x++) { var curNdx = 0; while(curNdx < exp.Length) { var chx = exp[curNdx]; if (chx == _Escape) { if (isEscaped) { isEscaped = false; sb.Append(chx); // append escaped character. curNdx++; continue; } isEscaped = true; curNdx++; continue; } if (!isEscaped && chx == _Section_Start) { AppendContentFromSectionExpression(sb, exp, ref curNdx, namedPatterns); continue; // skip to next character - index has already been forwarded to new position } // check are we entering a set pattern that may include a quantifier // Format = "[Vv]{4}" = generate 4 random ordered characters comprising of either V or v characters if (!isEscaped && chx == _Set_Start) { AppendContentFromSetExpression(sb, exp, ref curNdx); continue; // skip to next character - index has already been forwarded to new position } if (!isEscaped && chx == _NamedPattern_Start) { AppendContentFromNamedPattern(sb, exp, ref curNdx, namedPatterns); continue; } // check are we entering a repeat symbol section // Format = "L{4}" = repeat L symbol 4 times. bool repeatSymbol = curNdx < exp.Length - 1 && exp[curNdx + 1] == _Quantifier_Start; if (repeatSymbol) { AppendRepeatedSymbol(sb, exp, ref curNdx, isEscaped); isEscaped = false; continue; // skip to next character - index has already been forwarded to new position } AppendCharacterDerivedFromSymbol(sb, chx, isEscaped); curNdx++; // increment to move to next character. isEscaped = false; } } }
/// <summary> /// Calculates the content from a repeated expression when the following form is enountered '[exp]{repeat}'. /// </summary> /// <param name="sb"></param> /// <param name="characters"></param> /// <param name="index"></param> /// <param name="namedPatterns"></param> /// <param name="random"></param> private static void AppendContentFromSectionExpression(StringBuilder sb, string characters, ref int index, NamedPatterns namedPatterns, Random random) { var contentOptions = GetContentOptions(characters, ref index, _Section_Start.ToString(CultureInfo.InvariantCulture), _Section_End.ToString(CultureInfo.InvariantCulture), random); var exp = contentOptions.Content; if (contentOptions.ContainsAlternation) // contains alternations { GenerateFromAlternatedPattern(sb, namedPatterns, exp, contentOptions, random); return; } for (int x = 0; x < contentOptions.Repeat; x++) { ProcessPattern(sb, exp, namedPatterns, random); } }
private static void AppendContentFromNamedPattern(StringBuilder sb, string characters, ref int index, NamedPatterns namedPatterns) { var ndx = index; var tuple = GetContentOptions(characters, ref index, _NamedPattern_Start, _NamedPattern_End); if (namedPatterns.HasPattern(tuple.Content)) // $namedPattern; { sb.Append(GenerateFromPattern(namedPatterns.GetPattern(tuple.Content).Pattern, namedPatterns)); } else { var msg = BuildErrorSnippet(characters, ndx); msg = "Found named pattern placeholder '" + tuple.Content + "' but was not provided with a corresponding pattern Check Named Patterns file." + Environment.NewLine + msg; throw new GenerationException(msg); } }
private static void GenerateFromAlternatedPattern(StringBuilder sb, NamedPatterns namedPatterns, string exp, ContentOptions contentOptions) { var alternates = exp.Split(_Alternation); for (int x = 0; x < contentOptions.Repeat; x++) { exp = alternates[Random.Next(0, alternates.Length)]; sb.Append(GenerateFromPattern(exp, namedPatterns)); } }
private static void AppendPatternsFromConfigToCollection(GenerationConfig config, NamedPatterns patternCollection) { if (config.PatternFiles == null) { return; } foreach (var patternFile in config.PatternFiles) { var correctedPath = FileReader.GetPatternFilePath(patternFile); try { var patt = FileReader.LoadNamedPatterns(correctedPath); foreach (var pattern in patt.Patterns) { patternCollection.Patterns.Add(pattern); } } catch (Exception ex) { throw new GenerationException("Error loading PatternFile:" + patternFile + "\n\n" + ex.Message); } } }
/// <summary> /// Takes in a string that contains 0 or more <<placeholder>> values and replaces the placeholder item with the expression it defines. /// </summary> /// <param name="template"></param> /// <param name="namedPatterns"></param> /// <param name="generationConfig"></param> /// <returns></returns> public static string GenerateFromTemplate(string template, NamedPatterns namedPatterns, GenerationConfig generationConfig) { int index = 0; // CONFIG if (generationConfig == null) { generationConfig = LoadAndRemoveConfigFromTemplate(ref template); } if (generationConfig == null) { generationConfig = new GenerationConfig(); } var random = generationConfig.Random; // PATTERNS var generationPatterns = LoadDefaultNamedPatterns(generationConfig); // Load provided ones as well if there are any. if (namedPatterns != null && namedPatterns.Patterns != null) { namedPatterns.Patterns.ForEach(generationPatterns.Patterns.Add); } // Load all from the PatternFiles in config AppendPatternsFromConfigToCollection(generationConfig, generationPatterns); var sb = new StringBuilder(); while (index < template.Length) { // Find our next placeholder int start = FindPositionOfNext(template, index, _Placeholder_Start, _Placeholder_End); if (start == -1) { sb.Append(template.Substring(index)); //add remaining string. break; // all done! } bool isEscaped = IsEscaped(template, start); //start >= 1 && template[start - 1].Equals(_Escape); if (isEscaped) { start = start - 1; } sb.Append(template.Substring(index, start - index)); // Append everything up to start as it is. if (isEscaped) { start = start + 1; } start = start + _Placeholder_Start.Length; // move past '<<' to start of expression int end = FindPositionOfNext(template, start, _Placeholder_End, _Placeholder_Start); // find end of placeholder if (end == -1) { throw new GenerationException("Unable to find closing placeholder after " + start); } var pattern = template.Substring(start, end - start); // grab our expression if (isEscaped) { sb.Append("<<" + pattern + ">>"); } else { GenerateFromPattern(sb, pattern, generationPatterns, null, random); // generate value from expression } index = end + 2; // update our index. } return(sb.ToString()); }
/// <summary> /// Takes in a string that contains 0 or more <<placeholder>> values and replaces the placeholder item with the expression it defines. /// </summary> /// <param name="template"></param> /// <param name="namedPatterns"></param> /// <returns></returns> public static string GenerateFromTemplate(string template, NamedPatterns namedPatterns) { return(GenerateFromTemplate(template, namedPatterns, null)); }
/// <summary> /// /// </summary> /// <param name="pattern"> /// The format of the text produced. 15 random characters is the default. /// . - An uppercase or lowercase letter or number. /// w - Any Letter. /// L - An uppercase Letter. /// l - A lowercase letter. /// V - An uppercase Vowel. /// v - A lowercase vowel. /// C - An uppercase Consonant. /// c - A lowercase consonant. /// n - Any number, 1-9. /// d - Any number, 0-9. /// ------- /// Patterns can be produced: /// "\.{10}" will produce a random string 10 characters long. /// </param> /// <param name="namedPatterns"></param> /// <returns></returns> public static string GenerateFromPattern(string pattern, NamedPatterns namedPatterns) { if (pattern == null) { throw new GenerationException("Argument 'pattern' cannot be null."); } var sb = new StringBuilder(); bool isEscaped = false; int index = 0; while (index < pattern.Length) { char ch = pattern[index]; // check for escape chars for next part if (ch == _Escape) { if (isEscaped) { sb.Append(@"\"); isEscaped = false; index++; continue; } isEscaped = true; index++; continue; } // check are we entering a repeat pattern section that may include a quantifier // Format = "(LL){n,m}" = repeat xx pattern 4 times. if (!isEscaped && ch == _Section_Start) { AppendContentFromSectionExpression(sb, pattern, ref index, namedPatterns); continue; // skip to next character - index has already been forwarded to new position } // check are we entering a set pattern that may include a quantifier // Format = "[Vv]{4}" = generate 4 random ordered characters comprising of either V or v characters if (!isEscaped && ch == _Set_Start) { AppendContentFromSetExpression(sb, pattern, ref index); continue; // skip to next character - index has already been forwarded to new position } // check are we entering a repeat symbol section // Format = "L{4}" = repeat L symbol 4 times. bool repeatSymbol = index < pattern.Length - 1 && pattern[index + 1] == _Quantifier_Start; if (repeatSymbol) { AppendRepeatedSymbol(sb, pattern, ref index, isEscaped); isEscaped = false; continue; // skip to next character - index has already been forwarded to new position } // check if we have encountered a named pattern. if (!isEscaped && ch == _NamedPattern_Start) { AppendContentFromNamedPattern(sb, pattern, ref index, namedPatterns); continue; } AppendCharacterDerivedFromSymbol(sb, ch, isEscaped); isEscaped = false; index++; } return(sb.ToString()); }
/// <summary> /// Takes in a string that contains 0 or more <<placeholder>> values and replaces the placeholder item with the expression it defines. /// </summary> /// <param name="template"></param> /// <param name="namedPatterns"></param> /// <returns></returns> public static string GenerateFromTemplate(string template, NamedPatterns namedPatterns) { var sb = new StringBuilder(); int index = 0; while (index < template.Length) { // Find our next placeholder int start = FindPositionOfNext(template, index, _Placeholder_Start, _Placeholder_End); if (start == -1) { sb.Append(template.Substring(index)); //add remaining string. break; // all done! } bool isEscaped = start > 2 && template[start - 1].Equals(_Escape) && template[start - 2].Equals(_Escape); if (isEscaped) start = start - 2; sb.Append(template.Substring(index, start - index)); // Append everything up to start as it is. if (isEscaped) start = start + 2; start = start + 2; // move past '<<' to start of expression int end = FindPositionOfNext(template, start, _Placeholder_End, _Placeholder_Start); // find end of placeholder if (end == -1) { throw new GenerationException("Unable to find closing placeholder after "+start); } var pattern = template.Substring(start, end - start); // grab our expression if (isEscaped) sb.Append("<<"+pattern+">>"); else sb.Append(GenerateFromPattern(pattern, namedPatterns)); // generate value from expression index = end+2; // update our index. } return sb.ToString(); }