Потерянные пробелы в строках с CSV для функции массива - PullRequest
0 голосов
/ 25 октября 2011

Я работаю с функцией, которая преобразует данные CSV в многомерный массив. Затем я перебираю символы, чтобы найти конкретные ситуации в способе обработки строк в массиве. Например, если у меня есть строка типа - «это строка, да» - тогда я стараюсь не считать запятую в строке, потому что она находится между кавычками из этой строки. В любом случае, в следующей функции я потерял пробелы в результатах. Вместо того, чтобы получать «это AS3», я получаю «это AS3». Кажется, пробелы доступны только в строках с кавычками. Кто-нибудь имеет представление о том, где проблема в этой части кода?

        function CSVtoArray(csv:String):Array {
        var inQuotes:Boolean = false;
        var field:String = "";
        var finalData:Array = new Array();
        finalData.push(new Array());
        var line:int = 0;
        //iterate each character
        for(var i:int = 0; i < csv.length; i++) {
            var c:String = csv.charAt(i);
            var n:String = csv.charAt(i+1);
            var ad:Boolean = false;  
            //if the quote repeats, add the character
            if(inQuotes && c == "\"" && n == "\"") {
                field += c; 
            }            
            //if we are inside quotes, add the character
            if(inQuotes && c != "\"") {
                field += c;    
            }     
            //if we are not inside quotes...
            if(!inQuotes && c != "\"") {
                //if this character is a comma, start a new field
                if(c == ",") {
                    finalData[line].push(field);
                    field = "";   
                //if this character is a newline, start a new line
                } else if(c == "\n") {
                    finalData[line].push(field);
                    finalData.push(new Array());
                    line++;
                    field = "";     
                //if this is not leading or trailing white space, add the character
                } else if(c != " " && c != "\t" && c != "\r") {
                    field += c;
                }            
            }      
            //if this is a quote, switch inQuotes
            if(c == "\"") {
                inQuotes = !inQuotes;
            }      
        }      
        //add last line
        finalData[line].push(field);
        //if the last line does not have the same length as the first, remove it
        if(finalData[line].length < finalData[0].length) finalData.pop();



        //return the resulting array
        return finalData;

    }

Спасибо за любую помощь в этом очень ценится!

1 Ответ

0 голосов
/ 25 октября 2011

Похоже, вы могли бы использовать класс Tokenizer или какой-то уже существующий парсер.

Когда я выполняю вашу функцию как:

var result:String = CSVtoArray("\"this is a string, yeah\"");

Работает как положено - получаю строку с пробелами.

Ваша логика работает только для строк в кавычках:

//if we are not inside quotes...
if(!inQuotes && c != "\"") {
// ...
    //if this is not leading or trailing white space, add the character
    } else if(c != " " && c != "\t" && c != "\r") {
        field += c;

Если вы не в кавычках, и символ не является пробелом, он добавляется.

Итак, когда вы не в кавычках и не видите пробела, он не добавляется в строку.

На самом деле, это может быть достигнуто с помощью 1 строки RegEx.

Расширение на однострочный CSV-анализатор Taytay , вот пример реализации:

CsvParser.as

package
{
    import flash.display.Sprite;

    public class CsvParser extends Sprite
    {
        public function CsvParser()
        {
            var set1:Array = CSVtoArray("\"this is a string, yeah\"\n");
            var set2:Array = CSVtoArray("this is a string, yeah\n");
        }

        public function CSVtoArray(csv:String):Array
        {
            // split csv in to rows
            var rows:Array = csv.split("\n");

            // for every row...
            for (var x:uint = 0; x < rows.length; x++)
            {
                var columns:Array = csv.split(/,(?=(?:[^\"]*\"[^\"]*\")*(?![^\"]*\"))/g);

                for (var y:uint = 0; y < columns.length; y++)
                {
                    // trim leading / trailing whitespace
                    columns[y] = columns[y].replace(/^\s+|\s+$/g, '');
                }

                rows[x] = columns;
            }

            return (rows);
        }

    }
}
...