public static int IndexOfEndDelimiter( this string str, int startPos, ESCAPE_TYPES escapeType, bool anyDelimiterCanClose, params char[] astrDelimitersCaseINsensitive ) { int endSplit = 0; for (int i = startPos; i < str.Length; i++) { while (i < str.Length && !astrDelimitersCaseINsensitive.ContainsCaseInsensitive(str[i])) { i++; } if (i < str.Length) { // Should splitters also be case insensitive? I'm going to say yes. if (astrDelimitersCaseINsensitive.ContainsCaseInsensitive(str[i])) { // Remember which of the astrSplittingTokens was found to find the right closing char. char[] closingChars = anyDelimiterCanClose ? astrDelimitersCaseINsensitive // any delimiter can close the pattern. : new[] { str[i] }; // only the found delimiter can close. i++; while (i < str.Length) { if (closingChars.ContainsCaseInsensitive(str[i])) { if (escapeType.Equals(ESCAPE_TYPES.DOUBLED_CHAR) && i + 1 < str.Length && closingChars.ContainsCaseInsensitive(str[i + 1])) { i = i + 2; } else if (escapeType.Equals(ESCAPE_TYPES.BACKSLASH_BEFORE) && i > 0 && str[i - 1].Equals('\\')) { i++; } else { // Found the [unescaped] end tag. endSplit = i; break; } } else { i++; } } } } } return(endSplit); }
public static int IndexOfOutsideOfDelimitersCaseSensitive( this string str, string strToFind, int startPos, ESCAPE_TYPES escapeType, bool anyDelimiterCanClose, params char[] astrDelimiters ) { int ret = -1; int i = startPos; while (i < str.Length) { if ( astrDelimiters.Contains(str[i]) && !_isEscaped(str, escapeType, i) ) { // Remember which of the astrSplittingTokens was found to find the right closing char. char[] closingChars = anyDelimiterCanClose ? astrDelimiters // any delimiter can close the pattern. : new[] { str[i] }; // only the found delimiter can close. i++; while ( i < str.Length && ( !closingChars.Contains(str[i]) || _isEscaped(str, escapeType, i) ) ) { i++; } i++; // get past the matching end delimiter. } if ( i < str.Length && str[i].Equals(strToFind[0]) && (i - 1 + strToFind.Length) < str.Length && str.Substring(i, strToFind.Length).Equals(strToFind) ) { ret = i; break; } i++; } return(ret); }
private static bool _isEscaped(string str, ESCAPE_TYPES escapeType, int pos) { bool ret = false; switch (escapeType) { case ESCAPE_TYPES.BACKSLASH_BEFORE: ret = pos > 0 && str[pos - 1].Equals('\\') && !(pos > 1 && str[pos - 2].Equals('\\')); break; case ESCAPE_TYPES.DOUBLED_CHAR: ret = pos + 1 < str.Length && str[pos + 1].Equals(str[pos]); break; } return(ret); }