разделителен формат

Изглежда не мога да намеря това никъде в stackoverflow, така че ето го:

Имам файл, искам да разбера дали е разделен с тръба (|) или запетая (,). Също така искам да кажа дали квалификаторът на текста е quote(") или нищо. Някой има ли C# функции, които правят това? Благодаря!


person Badmiral    schedule 07.05.2012    source източник
comment
Открийте какъв разделител се използва? Каква евристика имахте предвид?   -  person Oded    schedule 07.05.2012
comment
По принцип търсете в низ и се опитайте да го анализирате и да поставите разделителя в някакъв символ или низ   -  person Badmiral    schedule 07.05.2012
comment
Знаете ли нещо за данните, като например броя на елементите на ред?   -  person Servy    schedule 07.05.2012
comment
За произволен файл ли имаш предвид? Какво знаете за тези файлове?   -  person Oded    schedule 07.05.2012
comment
Изберете разделител и пребройте колко пъти се среща в значителен брой редове. Ако винаги се среща същия брой пъти като броя на колоните, това вероятно е вашият разделител. Ако другият разделител ви даде същия резултат, вие сте прецакан. Ако нито един разделител не даде този резултат, трябва да приложите повече допускания.   -  person Igby Largeman    schedule 07.05.2012


Отговори (3)


За текстово разделени файлове като този намирам TextFieldParser да бъде много полезен инструмент. (Можете да импортирате Visual Basic dll, за да го използвате в C# приложение).

Общата стратегия, която бих използвал, тъй като според вас има фиксиран брой колони на файл, би била да избера разделител и да продължа анализирането/четенето на редове, докато един ред има различен брой колони от предишния ред. Когато това се случи, превключете към другия разделител (не съм сигурен какво искате да направите, ако и двата са невалидни). Може също да искате да изхвърлите разделителя, ако изобщо не е намерен на първия ред. Използване на TextFieldParser с HasFieldEnclosedInQuotes, зададен на вярно можете да обработвате правилно полета, които са екранирани в кавички (ще работи добре, ако не се използват кавички). Това ще бъде много по-лесно, отколкото да се опитвате ръчно да обработвате кавички, когато използвате обикновена манипулация на низове.

person Servy    schedule 07.05.2012

Това не ми е на ум и ако приемем, че файлът има равен брой колони и имате списък със знаци, които са възможни разделители.

char[] delims = { '|', ',', ... };

Вземете подмножество от редовете или целия файл, ако е достатъчно малък, и ги запазете в низов масив.

string[] lines = text.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);

Преминете през разделителите, като вмъкнете броя на разделените записи, използващи този разделител, в масив от int:

int[] counts = lines.Select(s => s.Split(currentDelimiter).Length).ToArray();

Използвайте свой собствен метод, за да видите, че всички преброявания се равняват и всички са по-големи от 1. Разделителят, на който сте, е този, който трябва да използвате.

person Derreck Dean    schedule 07.05.2012
comment
Има твърде много предположения. OP не е дал почти достатъчно подробности, за да бъде формулиран отговор - само предположения. - person Oded; 07.05.2012
comment
Много списъци, разделени със запетая/тръбна черта, няма да имат еднакъв брой елементи във всеки ред и вие също трябва да вземете предвид факта, че някои от разделителите може да са вътре в квалификатори на низ, което би било проблем за вашето преброяване. - person Servy; 07.05.2012
comment
Добра гледна точка, @Servy. Това може да е дубликат на stackoverflow.com/questions/761932/ - person Derreck Dean; 07.05.2012

Вземете първия (или втория ред, ако първият е заглавка с имена на файлове).

След това можете да използвате regex, за да проверите възможните формати. т.е.

 Regex rePipesAndQualifier = ("[^|"]*"|);

Ако rePipesAndQualifier.match(yourFileLine); върне няколко непразни съвпадения, тогава знаете, че използва тръби като разделители и има разделители.

Направете още регулярен израз, за ​​да проверите за разделени със запетая и със и без квалификатор.

Зависи малко от това какво очаквате да получите (всички разделени, само ограничени низове) и какво знаете (разделителите са в началото и края или само в средата, броя на полетата и т.н.). Ето защо не мога да ви дам точно решение.

person JotaBe    schedule 07.05.2012
comment
Файлът, разделен с вертикална черта, може да има полета със запетаи, а файлът, разделен със запетая, може да има полета с вертикална черта. Съществуването на едното и другото [само] не ви казва нищо. - person Servy; 07.05.2012
comment
ако може да има смесица от всичко и нямате extar информация, използвайте кристална топка. Сериозно, трябва да има нещо, което знаете предварително. - person JotaBe; 07.05.2012
comment
Да, и затова попитахме ОП какво знае или на какво иска да базира решението, вместо просто да изберем нещо, което няма да знаем, че работи. - person Servy; 07.05.2012
comment
За да бъде предложен смислен алгоритъм, човек наистина се нуждае от допълнителна информация над това, което публикува OP. Както коментира @Servy, вие сте отговорили без да имате такава информация. - person Oded; 07.05.2012
comment
Знаете, че имате файл с еднакъв брой колони във всеки ред, с изключение на това, че не знаете нищо: той е разделен с вертикална черта или запетая, може да има текстов квалификатор или не, и знаете, че всеки ред има същото брой колони - person Badmiral; 07.05.2012
comment
Моля, актуализирайте въпроса си с някои примери: ако ред има разделител, всички редове ще използват ли един и същ разделител? знаеш ли предварително броя на полетата? Един регулярен израз може да обработва и двата вида разделители, както и да изхвърли разделителите на кавички, ако съществуват. - person JotaBe; 08.05.2012
comment
@Servy. Моят отговор е насока как той може да реши проблема. Разбира се, това не е точното решение, тъй като нямам цялата необходима информация. Когато направя този вид следване по този начин отговор, ако ми бъде дадена допълнителна информация, аз я редактирам и подобрявам. Също така насърчавам ОП да редактира въпроса си, за да включи липсващата информация, така че въпросът да стане полезен за други хора без допълнителната информация в коментарите. - person JotaBe; 08.05.2012