示例#1
0
        public static ArrayList ConvertCSV(string csvText, bool removeTitle = false)
        {
            int len   = csvText.Length;
            int begin = 0;

            while (Convert.ToInt32(csvText[begin]) == 0xFEFF && begin < len)
            {
                begin += 1;
            }
            ArrayList rows = new ArrayList();
            ArrayList cols = new ArrayList();

            int  startIdx         = begin;
            int  lastIdx          = begin;
            bool skipRow          = removeTitle;
            bool needsQuoteEscape = false;

            CSVParserState state = CSVParserState.Begin;

            for (int i = begin; i < len; ++i)
            {
                char c = csvText[i];
                switch (c)
                {
                case ',':
                    switch (state)
                    {
                    case CSVParserState.Begin:
                        cols.Add("");
                        break;

                    case CSVParserState.Plane:
                    case CSVParserState.End:
                        string item = csvText.Substring(startIdx, lastIdx + 1 - startIdx);
                        cols.Add(needsQuoteEscape ? item.Replace("\"\"", "\"") : item);
                        needsQuoteEscape = false;
                        state            = CSVParserState.Begin;
                        break;

                    case CSVParserState.Quote:
                        lastIdx = i;
                        break;
                    }
                    break;

                case ' ':
                case '\t':
                    switch (state)
                    {
                    case CSVParserState.Plane:
                        break;

                    case CSVParserState.Quote:
                        lastIdx = i;
                        break;

                    case CSVParserState.Begin:
                    case CSVParserState.End:
                        break;
                    }
                    break;

                case '\r':
                    if (i < len - 1 && csvText[i + 1] == '\n')
                    {
                        i += 1;
                    }
                    goto case '\n';

                // Fallthrough
                case '\n':
                    switch (state)
                    {
                    case CSVParserState.Plane:
                    case CSVParserState.End:
                        string item = csvText.Substring(startIdx, lastIdx + 1 - startIdx);
                        cols.Add(needsQuoteEscape ? item.Replace("\"\"", "\"") : item);
                        needsQuoteEscape = false;
                        if (!skipRow)
                        {
                            cols.TrimToSize();
                            rows.Add(cols);
                        }
                        else
                        {
                            skipRow = false;
                        }
                        cols  = new ArrayList(cols.Count);
                        state = CSVParserState.Begin;
                        break;

                    case CSVParserState.Begin:
                        if (cols.Count > 0)
                        {
                            cols.Add("");
                            if (!skipRow)
                            {
                                cols.TrimToSize();
                                rows.Add(cols);
                            }
                            else
                            {
                                skipRow = false;
                            }
                            cols = new ArrayList(cols.Count);
                        }
                        break;

                    case CSVParserState.Quote:
                        // NOTE:
                        //  ダブルクォート中に改行が入っていたらCSVとして壊れているはずだが、
                        //  互換性を持たせるために従来のアルゴリズムと同じく許容する。 - ykst
                        lastIdx = i;
                        break;
                    }
                    break;

                case '"':
                    switch (state)
                    {
                    case CSVParserState.Begin:
                        startIdx = i + 1;
                        lastIdx  = i;
                        state    = CSVParserState.Quote;
                        break;

                    case CSVParserState.End:
                    case CSVParserState.Plane:
                        throw new System.ApplicationException("error CSV");

                    case CSVParserState.Quote:
                        if (i < len - 1)
                        {
                            if (csvText[i + 1] == '"')
                            {
                                i += 1;
                                needsQuoteEscape = true;
                                lastIdx          = i;
                            }
                            else
                            {
                                state = CSVParserState.End;
                            }
                        }
                        else
                        {
                            state = CSVParserState.End;
                        }
                        break;
                    }
                    break;

                default:
                    switch (state)
                    {
                    case CSVParserState.Begin:
                        startIdx = i;
                        lastIdx  = i;
                        state    = CSVParserState.Plane;
                        break;

                    case CSVParserState.End:
                        Debug.LogError("Unanalyzable CSV, using legacy one");
                        return(LegacyConvertCSV(csvText, removeTitle));

                    case CSVParserState.Plane:
                    case CSVParserState.Quote:
                        lastIdx = i;
                        break;
                    }
                    break;
                }
            }

            switch (state)
            {
            case CSVParserState.Begin:
                if (cols.Count > 0 && !skipRow)
                {
                    cols.Add("");
                    cols.TrimToSize();
                    rows.Add(cols);
                }
                break;

            case CSVParserState.End:
            case CSVParserState.Plane:
                if (!skipRow)
                {
                    cols.Add(csvText.Substring(startIdx, lastIdx + 1 - startIdx));
                    cols.TrimToSize();
                    rows.Add(cols);
                }
                break;

            case CSVParserState.Quote:
                throw new System.ApplicationException("error CSV");
            }
            return(rows);
        }
示例#2
0
    /// <summary>
    /// Convert String to CSV
    /// </summary>
    /// <param name="csvText">string of CSV</param>
    /// <param name="removeFirstRow">Flag whether ignore the first row</param>
    /// <returns></returns>
    public static ArrayList ConvertCSV(string csvText, bool removeFirstRow = true)
    {
        int len   = csvText.Length;
        int begin = 0;

        // If the text contains BOM, skip the first index.
        // Otherwise BOM will be included in the data
        while (Convert.ToInt32(csvText[begin]) == 0xFEFF && begin < len)
        {
            begin += 1;
        }

        ArrayList rows = new ArrayList();
        ArrayList cols = new ArrayList();

        int  startIdx         = begin;
        int  lastIdx          = begin;
        bool skipRow          = removeFirstRow;
        bool needsQuoteEscape = false;

        CSVParserState state = CSVParserState.BEGIN_FIELD;

        for (int i = begin; i < len; ++i)
        {
            char c = csvText[i];
            switch (c)
            {
            case ',':
                switch (state)
                {
                case CSVParserState.BEGIN_FIELD:
                    cols.Add("");
                    break;

                case CSVParserState.PLAIN:
                case CSVParserState.END_FIELD:
                    string item = csvText.Substring(startIdx, lastIdx + 1 - startIdx);
                    cols.Add(needsQuoteEscape ? item.Replace("\"\"", "\"") : item);
                    needsQuoteEscape = false;
                    state            = CSVParserState.BEGIN_FIELD;
                    break;

                case CSVParserState.QUOTE:
                    lastIdx = i;
                    break;
                }
                break;

            case ' ':
            case '\t':
                switch (state)
                {
                case CSVParserState.PLAIN:
                    break;

                case CSVParserState.QUOTE:
                    lastIdx = i;
                    break;

                case CSVParserState.BEGIN_FIELD:
                case CSVParserState.END_FIELD:
                    break;
                }
                break;

            case '\r':
                if (i < len - 1 && csvText[i + 1] == '\n')
                {
                    i += 1;
                }
                goto case '\n';

            // Fallthrough
            case '\n':
                switch (state)
                {
                case CSVParserState.PLAIN:
                case CSVParserState.END_FIELD:
                    string item = csvText.Substring(startIdx, lastIdx + 1 - startIdx);
                    cols.Add(needsQuoteEscape ? item.Replace("\"\"", "\"") : item);
                    needsQuoteEscape = false;
                    if (!skipRow)
                    {
                        cols.TrimToSize();
                        rows.Add(cols);
                    }
                    else
                    {
                        skipRow = false;
                    }
                    cols  = new ArrayList(cols.Count);
                    state = CSVParserState.BEGIN_FIELD;
                    break;

                case CSVParserState.BEGIN_FIELD:
                    if (cols.Count > 0)
                    {
                        cols.Add("");
                        if (!skipRow)
                        {
                            cols.TrimToSize();
                            rows.Add(cols);
                        }
                        else
                        {
                            skipRow = false;
                        }
                        cols = new ArrayList(cols.Count);
                    }
                    break;

                case CSVParserState.QUOTE:
                    lastIdx = i;
                    break;
                }
                break;

            case '"':
                switch (state)
                {
                case CSVParserState.BEGIN_FIELD:
                    startIdx = i + 1;
                    lastIdx  = i;
                    state    = CSVParserState.QUOTE;
                    break;

                case CSVParserState.END_FIELD:
                case CSVParserState.PLAIN:
                    throw new ApplicationException("Incorrect format CSV.");

                case CSVParserState.QUOTE:
                    if (i < len - 1)
                    {
                        if (csvText[i + 1] == '"')
                        {
                            i += 1;
                            needsQuoteEscape = true;
                            lastIdx          = i;
                        }
                        else
                        {
                            state = CSVParserState.END_FIELD;
                        }
                    }
                    else
                    {
                        state = CSVParserState.END_FIELD;
                    }
                    break;
                }
                break;

            default:
                switch (state)
                {
                case CSVParserState.BEGIN_FIELD:
                    startIdx = i;
                    lastIdx  = i;
                    state    = CSVParserState.PLAIN;
                    break;

                case CSVParserState.END_FIELD:
                    throw new System.ApplicationException("Could not parse CSV: extra character found outside quotation.");

                case CSVParserState.PLAIN:
                case CSVParserState.QUOTE:
                    lastIdx = i;
                    break;
                }
                break;
            }
        }

        switch (state)
        {
        case CSVParserState.BEGIN_FIELD:
            if (cols.Count > 0 && !skipRow)
            {
                cols.Add("");
                cols.TrimToSize();
                rows.Add(cols);
            }
            break;

        case CSVParserState.END_FIELD:
        case CSVParserState.PLAIN:
            if (!skipRow)
            {
                cols.Add(csvText.Substring(startIdx, lastIdx + 1 - startIdx));
                cols.TrimToSize();
                rows.Add(cols);
            }
            break;

        case CSVParserState.QUOTE:
            throw new System.ApplicationException("Incorrect format CSV.");
        }
        return(rows);
    }