1096 lines · 42.2 KB · C#
RawDownload
//******************************************************************************************************//  StringParser.cs - Gbtc////  Copyright © 2017, Grid Protection Alliance.  All Rights Reserved.////  Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See//  the NOTICE file distributed with this work for additional information regarding copyright ownership.//  The GPA licenses this file to you under the MIT License (MIT), the "License"; you may//  not use this file except in compliance with the License. You may obtain a copy of the License at:////      http://www.opensource.org/licenses/MIT////  Unless agreed to in writing, the subject software distributed under the License is distributed on an//  "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the//  License for the specific language governing permissions and limitations.////  Code Modification History://  ----------------------------------------------------------------------------------------------------//  07/01/2017 - F. Russell Robertson//       Generated original version of source code.////******************************************************************************************************using System;using System.Diagnostics.CodeAnalysis;using System.Linq; namespace GSF.Parsing{    /// <summary>    /// Like the Excel CSV Parser, only better.    /// </summary>    public static class StringParser    {        private const char quoteDoubleChar = '\"';        private const char quoteSingleChar = '\"';        private const char spaceChar = ' ';        private const char commaChar = ',';        private const string crLf = "\r\n";        private const int workingArraySize = 128;          /// <summary>        /// Returns the string that is between two delimiter strings beginning the first startDelimiter found.        /// ALSO, returns the index of the payload (the index of the first char past the startDelimiter)        /// </summary>        /// <param name="inString">The input string</param>        /// <param name="startToken">The beginning token or delimiter</param>        /// <param name="endToken">The ending token or delimiter</param>        /// <param name="startIndex">The index on which to begin searching inString</param>        /// <param name="matchCase">set to FALSE for case insensitive test for delimiters</param>        /// <param name="includeTokensInReturn">set to TRUE for the return string to include the opening and closing tokens.</param>        /// <param name="payloadIndex"></param>        /// <returns>A string, and the string starting index (payload Index)</returns>        public static string GetBetweenDelimiters(string inString, out int payloadIndex, char startToken = ',', char endToken = ',',                             int startIndex = 0, bool matchCase = true, bool includeTokensInReturn = false)        {            payloadIndex = -1;             if (string.IsNullOrEmpty(inString))                return (null);             if (startIndex > inString.Length - 1 || startIndex < 0)                return (null);             string testString = inString;             if (!matchCase)            {                testString = inString.ToUpper();                startToken = startToken.ToUpper();                endToken = endToken.ToUpper();            }             int iStart = testString.IndexOf(startToken, startIndex);            if (iStart > -1)            {                iStart++;                int iEnd = testString.IndexOf(endToken, iStart);                if (iEnd > -1)                {                     //Are there other open tokens in this range                    int[] opentags = IndicesOfToken(testString.Substring(iStart, iEnd - iStart), startToken);                    //If so, reach to the matching closing Token                    if (opentags != null && opentags.Length > 0)                    {                         for (int i = 0; i < opentags.Length; i++)                        {                            iEnd++;                            iEnd = testString.IndexOf(endToken, iEnd);                            if (iEnd < 0) break;                        }                        if (iEnd < 0) return (null);                     }                     if (includeTokensInReturn)                    {                        payloadIndex = iStart - 1;                        return inString.Substring(payloadIndex, iEnd - iStart + 2);                    }                     payloadIndex = iStart;                    return inString.Substring(payloadIndex, iEnd - iStart);                }                else                    // no end delimiter                    return (null);            }            else                // no start delimiter                return (null);        }         /// <summary>        /// Returns an array indices where the token char was found.  Null for no tokens found.        /// </summary>        /// <param name="inString">The string to process</param>        /// <param name="token">The token string sought</param>        /// <param name="startIndex">The index from which to begin searching inString</param>        /// <param name="matchCase">Set to FALSE for case insensitive search</param>        /// <returns></returns>        public static int[] IndicesOfToken(string inString, char token, int startIndex = 0, bool matchCase = true)        {            if (string.IsNullOrEmpty(inString))                return null;             if (startIndex > inString.Length - 1 || startIndex < 0)                return null;             int[] indices = new int[workingArraySize];             if (token == 0)                return null;             int count = 0;            int k = IndexOfNextToken(inString, token, startIndex, 1, matchCase);            while (k > -1)            {                indices[count++] = k;                k = IndexOfNextToken(inString, token, k + 1, 1, matchCase);                if (count >= indices.Length)                    Array.Resize(ref indices, indices.Length + workingArraySize);            }            if (count == 0)            {                Array.Resize(ref indices, 1);                return null;            }             Array.Resize(ref indices, count);            return indices;        }         /// <summary>        /// Returns an array of indices where the token string was found        /// </summary>        /// <param name="inString">The string to process</param>        /// <param name="token">The token string sought</param>        /// <param name="startIndex">The index from which to begin searching inString</param>        /// <param name="matchCase">Set to FALSE for case insensitive search</param>        /// <returns>null for no tokens found</returns>        public static int[] IndicesOfToken(string inString, string token, int startIndex = 0, bool matchCase = true)        {             if (string.IsNullOrEmpty(inString))                return null;             if (startIndex > inString.Length - 1 || startIndex < 0)                return null;             int[] indices = new int[workingArraySize];             if (string.IsNullOrEmpty(token))                return null;             int count = 0;            int k = IndexOfNextToken(inString, token, startIndex, 1, matchCase);             while (k > -1)            {                indices[count++] = k;                k = IndexOfNextToken(inString, token, k + token.Length, 1, matchCase);                if (count >= indices.Length)                    Array.Resize(ref indices, indices.Length + workingArraySize);             }            if (count > 0)            {                Array.Resize(ref indices, count);                return indices;            }            return null;        }         /// <summary>        /// Returns an array of the indices where the token chars were found.  Null for no tokens found.        /// </summary>        /// <param name="inString">The string to process</param>        /// <param name="tokens">The char array of the tokens</param>        /// <param name="startIndex">The index from which to begin searching inString</param>        /// <param name="matchCase">Set to FALSE for case insensitive search</param>        /// <returns></returns>        public static int[] IndicesOfTokens(string inString, char[] tokens, int startIndex = 0, bool matchCase = true)        {            if (string.IsNullOrEmpty(inString))                return null;             if (startIndex > inString.Length - 1 || startIndex < 0)                return null;             int[] indices = new int[workingArraySize];             if (tokens == null || tokens[0] == 0)                return null;             int count = 0;            int k = IndexOfNextTokens(inString, tokens, startIndex, matchCase);             while (k > -1)            {                indices[count++] = k;                k = IndexOfNextTokens(inString, tokens, k + 1, matchCase);                if (count >= indices.Length)                    Array.Resize(ref indices, indices.Length + workingArraySize);            }             if (count == 0)            {                Array.Resize(ref indices, 1);                return null;            }             Array.Resize(ref indices, count);            return indices;        }         /// <summary>        ///  Finds the index of the "n" occurrence of a character (a token) within a string        /// </summary>        /// <param name="inString">The string to process.</param>        /// <param name="token">The token character sought</param>        /// <param name="startIndex">The index from which to begin searching inString</param>        /// <param name="occurrenceCount">The occurrence sought</param>        /// <param name="matchCase">Set to FALSE for case insensitive search</param>        /// <returns>Returns the starting index of the nth occurrence of a character.        ///  Returns -1 if nth occurrence does not exist.</returns>        public static int IndexOfNextToken(string inString, char token, int startIndex = 0, int occurrenceCount = 1, bool matchCase = true)        {            if (string.IsNullOrEmpty(inString))                return -1;             if (token == 0)                return -1;             if (occurrenceCount < 1)                return -1;             if (startIndex > inString.Length - 1 || startIndex < 0)                return -1;             if (!matchCase)            {                inString = inString.ToUpper();                token = token.ToUpper();            }             int count = 1;            int indexPos = inString.IndexOf(token, startIndex);             while (indexPos > -1 && count != occurrenceCount)            {                indexPos = inString.IndexOf(token, indexPos + 1);                count++;            }            return indexPos;        }         /// <summary>        ///  Finds the index of the "n" occurrence of one string (a token) within another        /// </summary>        /// <param name="inString">The string to process.</param>        /// <param name="token">The string to find</param>        /// <param name="startIndex">The index from which to begin searching inString</param>        /// <param name="occurrenceCount">The occurrence of the token sought</param>        /// <param name="matchCase">Set to FALSE for case insensitive search</param>        /// <returns>Returns the starting index of the nth occurrence of a string.         /// Returns -1 if nth occurrence does not exist.</returns>        public static int IndexOfNextToken(string inString, string token, int startIndex = 0, int occurrenceCount = 1, bool matchCase = true)        {            if (string.IsNullOrEmpty(inString))                return -1;             if (string.IsNullOrEmpty(token))                return -1;             if (occurrenceCount < 1)                return -1;             if (startIndex > inString.Length - 1 || startIndex < 0)                return -1;             if (!matchCase)            {                inString = inString.ToUpper();                token = token.ToUpper();            }             int count = 1;            int indexPos = inString.IndexOf(token, startIndex, StringComparison.Ordinal);             while (indexPos > -1 && count != occurrenceCount)            {                indexPos = inString.IndexOf(token, indexPos + 1, StringComparison.Ordinal);                count++;            }            return indexPos;        }          /// <summary>        ///  Finds the index of the "n" occurrence any one of the chars in the token array within a string        /// </summary>        /// <param name="inString">The string to process.</param>        /// <param name="tokens">The token characters sought</param>        /// <param name="startIndex">The index from which to begin searching inString</param>        /// <param name="matchCase">Set to FALSE for case insensitive search</param>        /// <returns>Returns the starting index of the nth occurrence of a character.        ///  Returns -1 if nth occurrence does not exist.</returns>        public static int IndexOfNextTokens(string inString, char[] tokens, int startIndex = 0, bool matchCase = true)         {            if (string.IsNullOrEmpty(inString))                return -1;             if (tokens == null)                return -1;             if (startIndex > inString.Length - 1 || startIndex < 0)                return -1;             if (inString.IndexOfAny(tokens, startIndex) < 0)                return -1;             int i = 0;             if (!matchCase)            {                inString = inString.ToUpper();                foreach (char c in tokens)                {                    tokens[i++] = c.ToUpper();                }            }             int[] positions = new int[tokens.Length];            i = 0;             foreach (char c in tokens)            {                positions[i] = inString.IndexOf(c, startIndex);                if (positions[i] < 0)                    positions[i] = 32000;                i++;            }             return positions.Min();         }         /// <summary>        ///  Processing from RIGHT to LEFT, finds the index of the "n" occurrence of a character (a token) within a string        /// </summary>        /// <param name="inString">The string to process.</param>        /// <param name="token">The token character sought</param>        /// <param name="startIndex">Default of zero (0) begins testing end of inString, otherwise        /// The index from with to begin processing inString from RIGHT to LEFT</param>        /// <param name="occurrenceCount">The occurrence sought</param>        /// <param name="matchCase">Set to FALSE for case insensitive search</param>        /// <returns>Returns the starting index of the nth occurrence of a character.        /// Returns -1 if nth occurrence does not exist.</returns>        public static int IndexOfPreviousToken(string inString, char token, int startIndex = 0, int occurrenceCount = 1, bool matchCase = true)        {            if (string.IsNullOrEmpty(inString))                return -1;             if (token == 0)                return -1;             if (occurrenceCount < 1)                return -1;             if (startIndex > inString.Length - 1 || startIndex < 0)                return -1;             if (startIndex == 0)                startIndex = inString.Length - 1;              if (!matchCase)            {                inString = inString.ToUpper();                token = token.ToUpper();            }             int count = 1;            int indexPos = inString.IndexOfPrevious(token, startIndex);             while (indexPos > -1 && count != occurrenceCount)            {                indexPos = inString.IndexOfPrevious(token, indexPos - 1);                count++;            }            return indexPos;        }          /// <summary>        ///  Processing from RIGHT to LEFT, finds the index of the "n"occurrence of one string (a token) within a string        /// </summary>        /// <param name="inString">The string to process.</param>        /// <param name="token">The token string sought</param>        /// <param name="startIndex">Default of zero (0) begins testing end of inString, otherwise        /// The index from with to begin processing inString from RIGHT to LEFT</param>        /// <param name="occurrenceCount">The occurrence sought</param>        /// <param name="matchCase">Set to FALSE for case insensitive search</param>        /// <returns>Returns the starting index of the nth occurrence of a string.        /// Returns -1 if nth occurrence does not exist.</returns>        public static int IndexOfPreviousToken(string inString, string token, int startIndex = 0, int occurrenceCount = 1, bool matchCase = true)        {            if (string.IsNullOrEmpty(inString))                return -1;             if (string.IsNullOrEmpty(token))                return -1;             if (occurrenceCount < 1)                return -1;             if (startIndex > inString.Length - 1 || startIndex < 0)                return -1;             if (startIndex == 0)                startIndex = inString.Length - 1;              if (!matchCase)            {                inString = inString.ToUpper();                token = token.ToUpper();            }             int count = 1;            int indexPos = inString.IndexOfPrevious(token, startIndex);             while (indexPos > -1 && count != occurrenceCount)            {                indexPos = inString.IndexOfPrevious(token, indexPos - 1);                count++;            }            return indexPos;        }         /// <summary>        /// Looks to the RIGHT for the first open token and returns the matching close token        /// </summary>        /// <param name="inString">The string to process</param>        /// <param name="openToken"></param>        /// <param name="closeToken"></param>        /// <param name="startIndex">The index from with to begin processing inString</param>        /// <param name="matchCase">Set to FALSE for case insensitive search</param>        /// <returns></returns>        public static int IndexOfMatchingCloseToken(string inString, string openToken, string closeToken, int startIndex = 0, bool matchCase = true)        {            if (string.IsNullOrEmpty(inString))                return -1;             if (string.IsNullOrEmpty(openToken))                return -1;             if (string.IsNullOrEmpty(closeToken))                return -1;             if (startIndex > inString.Length - 1 || startIndex < 0)                return -1;             if (!matchCase)            {                inString = inString.ToLower();                openToken = openToken.ToLower();                closeToken = closeToken.ToLower();            }             int openTokenIndex = inString.IndexOf(openToken, startIndex, StringComparison.Ordinal);            if (openTokenIndex < 0)                return -1;             if (startIndex + openToken.Length > inString.Length)                return -1;

Lines 1–500 of 1096.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t