using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace StringInputParseTester { public partial class Form1 : Form { public Form1() { InitializeComponent(); inputTextBox.Leave += ExecuteParserCode; } private string CapitalizeFirstLetter(string word) { if (string.IsNullOrEmpty(word)) return string.Empty; return word.First().ToString().ToUpperInvariant() + string.Join("", word.Skip(1)); } private void ExecuteParserCode(object sender, EventArgs e) { var adItemText = inputTextBox.Text.Trim(); //var splitInput = inputTextBox.Text.Split((char[])null, StringSplitOptions.RemoveEmptyEntries); var isInsideBrackets = false; var isPreviousCharWhiteSpace = false; //preserveAcronyms var preserveAcronyms = true; var cleanedInputString = ""; var lastnumberStartingIndex = -1; //Create an array of brackets to test for, and either balance out or simply ignore. char[] openBrackets = {'(', '<', '{', '['}; char[] closedBrackets = {')', '>', '}', ']'}; for (var currentCharacter = 0; currentCharacter < adItemText.Length; currentCharacter++) { //Capitalize the first character in the string and move to the next character. if (currentCharacter == 0) { cleanedInputString += char.ToUpperInvariant(adItemText[0]); continue; } //IF the current character is a whitespace character, mark it as such, add to the temporary string, and move on to the next. if (char.IsWhiteSpace(adItemText[currentCharacter])) { //Check for more then one space in a row. if (isPreviousCharWhiteSpace) { //If more then one space is found to be in a row, then ignore it and move onto the next character. continue; } //IF the current character is whitespace, then mark it and move onto the next loop. isPreviousCharWhiteSpace = true; cleanedInputString += adItemText[currentCharacter]; continue; } //IF the current character is an open bracket then mark it so we're inside brackets and move to the next character. if (openBrackets.Contains(adItemText[currentCharacter])) { if (isInsideBrackets) { //If we are already inside of brackets then don't add anymore to the string just continue. continue; } isInsideBrackets = true; //Just gonna force parenthesis for now. cleanedInputString += '('; continue; } //IF the current character is a closing bracket then mark it as such and move to the next character (if any). if (closedBrackets.Contains(adItemText[currentCharacter])) { //IF we're not inside brackets then there is an imbalance so discard this parenthesis. if (!isInsideBrackets) { continue; } //Just gonna force parenthesis for now. cleanedInputString += ')'; lastnumberStartingIndex = -1; //reset //Clear the current working word. isInsideBrackets = false; continue; } //IF the current character is not a number and the previous character is a white space character //then capitalize the current character and add it to the string. if (!char.IsNumber(adItemText[currentCharacter]) && isPreviousCharWhiteSpace) { //Check to see if the character before the whitespace is a number. if (char.IsNumber(cleanedInputString[cleanedInputString.Length - 2])) { var abbreviations = new List(); var words = new List(); BuildAbbreviationsAndWordsLists(adItemText, currentCharacter, out abbreviations, out words); //Remove the last space if there are any abbreviations or words found. if (abbreviations.Count > 0 || words.Count > 0) { cleanedInputString = cleanedInputString.Remove(cleanedInputString.Length - 1, 1); } //Begin checking to see how to place these items back into the final string. if (abbreviations.Count >= 1 && words.Count == 0) { if (!isInsideBrackets) { cleanedInputString += abbreviations[0] + ")"; if (lastnumberStartingIndex != -1) { cleanedInputString = cleanedInputString.Insert(lastnumberStartingIndex, "("); } } else { cleanedInputString += abbreviations[0] + ")"; } break; } if (abbreviations.Count >= 1 && words.Count == 1) { cleanedInputString += abbreviations[0] + " " + words[0]; //Clear all braces since this format doesn't allow for braces in this set up. cleanedInputString = cleanedInputString.Replace("(", ""); break; } if (abbreviations.Count >= 0 && words.Count >= 1) { if (abbreviations.Count != 0) { cleanedInputString += abbreviations[0]; } cleanedInputString = words.Aggregate(cleanedInputString, (current, word) => current + (" " + word)); //Clear all braces since this format doesn't allow for braces in this set up. cleanedInputString = cleanedInputString.Replace("(", ""); break; } } //Check to see the length of the string and determine if the word with the number needs to be capitalized. cleanedInputString += char.ToUpperInvariant(adItemText[currentCharacter]); } //However, if the current character is not a number but the previous character is NOT a white space character //then run a few checks before adding it to the string. else if (!char.IsNumber(adItemText[currentCharacter]) && char.IsLetter(adItemText[currentCharacter])) { //IF the previous character is a number... if (char.IsNumber(cleanedInputString[cleanedInputString.Length - 1])) { //Check to see the length of the string and determine if the word with the number needs to be capitalized. var abbreviations = new List(); var words = new List(); BuildAbbreviationsAndWordsLists(adItemText, currentCharacter, out abbreviations, out words); //Check to see if braces are necessary for the format we're going for. if (abbreviations.Count >= 1 && words.Count == 0) { if (!isInsideBrackets) { cleanedInputString += abbreviations[0] + ")"; if (lastnumberStartingIndex != -1) { cleanedInputString = cleanedInputString.Insert(lastnumberStartingIndex, "("); } } else { cleanedInputString += abbreviations[0] + ")"; } break; } if (abbreviations.Count >= 1 && words.Count == 1) { cleanedInputString += abbreviations[0] + " " + words[0]; //Clear all braces since this format doesn't allow for braces in this set up. cleanedInputString = cleanedInputString.Replace("(", ""); break; } if (abbreviations.Count >= 0 && words.Count >= 1) { if (abbreviations.Count != 0) { cleanedInputString += abbreviations[0]; } cleanedInputString = words.Aggregate(cleanedInputString, (current, word) => current + (" " + word)); //Clear all braces since this format doesn't allow for braces in this set up. cleanedInputString = cleanedInputString.Replace("(", ""); break; } } else if (char.IsLetter(adItemText[currentCharacter - 1])) { cleanedInputString += char.ToLowerInvariant(adItemText[currentCharacter]); } } //IF a number is found, and we're not inside brackets, check to see if there is an opening parenthesis and if there aren't create one. if (char.IsNumber(adItemText[currentCharacter])) { cleanedInputString += adItemText[currentCharacter]; if (lastnumberStartingIndex == -1) { lastnumberStartingIndex = cleanedInputString.Length - 1; //This is index based. } } //Check for any allowed punctuation. if (adItemText[currentCharacter] == '\'') { cleanedInputString += adItemText[currentCharacter]; } //Check if the previous character is an "'". else if (cleanedInputString[cleanedInputString.Length - 1] == '\'') { cleanedInputString += adItemText[currentCharacter]; } //Since whitespace booleans are handled above, set the boolean for white spaces false. //IF we've made it this far that means the current character is not a white space character. isPreviousCharWhiteSpace = false; //IF we're at the end of the string and we're inside brackets then balance out the open bracket. if ((currentCharacter + 1) == adItemText.Length && isInsideBrackets) { cleanedInputString += ')'; } } outputTextBox.Text = cleanedInputString; } /// /// Determines whether or not a string is an abbreviation or a word. /// A word is defined as being at least three (3) characters long and having /// at least one (1) vowel. Where as an abbreviation is defined as less then /// three (3) characters long or being exactly three characters long but having /// zero (0) vowels. /// /// The string to determine whether or not its a word. /// private bool IsWord(string text) { if (string.IsNullOrEmpty(text)) return false; var isWord = true; //Most abbreviations do not have vowels in them so check to see if the "abbreviation" //isn't just a short word like "Box", as opposed to "lbs". char[] vowels = {'a', 'e', 'i', 'o', 'u', 'y'}; //Count the number of vowels the word has. var vowelCount = text.Count(x => vowels.Contains(x)); //IF the string is exactly three (3) characters long and has more then zero (0) vowels then it is considered a word. if (text.Length == 3 && vowelCount == 0) { isWord = false; } else if (text.Length < 3) { isWord = false; } //Return the verdict. return isWord; } private void BuildAbbreviationsAndWordsLists(string adItemText, int startingIndex, out List abbreviations, out List words, bool preserveAcronyms = true) { abbreviations = new List(); words = new List(); var currentWorkingString = ""; //Starting at the next character, spin through and find all words or abbreviations that are separated by white space. for (var i = startingIndex; i < adItemText.Length; i++) { //If the current character is a letter and if so add it to the current working string. if (char.IsLetter(adItemText[i])) { currentWorkingString += adItemText[i]; } //Check for the current character being a white space, showing the end of a word or abbreviation. else if (char.IsWhiteSpace(adItemText[i])) { //Block against null values from messing things up. if (string.IsNullOrEmpty(currentWorkingString)) continue; //The end of what ever word we were on has been reached, so check to see what the string is. if (IsWord(currentWorkingString)) { words.Add(currentWorkingString); } else { abbreviations.Add(currentWorkingString); } //Clear the current working string to start on the next. currentWorkingString = ""; } //Run a check to see if this is the last character in the string. if ((i + 1) != adItemText.Length) continue; //The end of whatever word we were on has been reached, so check to see what the string is. if (IsWord(currentWorkingString)) { words.Add(currentWorkingString); } else { abbreviations.Add(currentWorkingString); } } //Clean the cases of the abbreviations and words. for (var i = 0; i < abbreviations.Count; i++) { //If preserve acronyms is set to true then just leave the cases of the abbreviations alone. if (!preserveAcronyms) { abbreviations[i] = abbreviations[i].ToLowerInvariant(); } } for (var i = 0; i < words.Count; i++) { words[i] = words[i].ToLowerInvariant(); words[i] = CapitalizeFirstLetter(words[i]); } } public string FormatShit(string inputString) { var finalString = ""; var workingText = ""; //The (char[])null avoids creating a new object in memory. var splitInput = inputString.Split((char[])null, StringSplitOptions.RemoveEmptyEntries); foreach (var text in splitInput) { //Clear the working text to start building the next one to test. workingText = ""; foreach (var character in text) { } } return finalString; } } }