|
v8:ИзСтрокиСРазделителями | ☑ | ||
---|---|---|---|---|
0
Serginio1
13.09.09
✎
13:55
|
Начал работать с 8 кой не нашел ИзСтрокиСРазделителями.
Переписал с# вариант из http://www.rsdn.ru/forum/dotnet/3303143.1.aspx Процедура ИзСтрокиСРазделителями(S,aList) ExtractFields(S,aList,",","""") КонецПроцедуры Процедура ExtractFields(S,aList,Delimiter,QuoteChar) FieldStart=0; ScanField=1; ScanQuoted=2; EndQuoted=3; //{initialize by clearing the string list, and // starting in FieldStart state} // Assert(aList <> nil, 'TDExtractFields: list is nil'); aList= новый Массив; if ( (S=неопределено) или (СтрДлина(S) =0 )) Тогда aList.Add(""); return; КонецЕсли; State = FieldStart; // RStringBuilder SB= new RStringBuilder(); SB=""; StartPos=1; EndPos=СтрДлина(S); Inx=1; // {read through all the characters in the string} while (Inx <=EndPos) Цикл // {get the next character} Ch = Сред(S,Inx,1); // {switch processing on the state} Если State =FieldStart Тогда if ( Ch = QuoteChar) Тогда State = ScanQuoted; StartPos=Inx+1; SB=""; else if ( Ch = Delimiter) Тогда aList.Add(""); else State = ScanField; StartPos=Inx; КонецЕсли; КонецЕсли; ИначеЕсли State =ScanField Тогда if ( Ch = Delimiter ) Тогда CopyCount=Inx-StartPos; aList.Add(Сред(S,StartPos,CopyCount)); State = FieldStart; КонецЕсли ИначеЕсли State = ScanQuoted Тогда if ( Ch = QuoteChar) Тогда State = EndQuoted; CopyCount=Inx-StartPos; // SB.Append(S,StartPos,CopyCount); SB=SB+Сред(S,StartPos,CopyCount); КонецЕсли; ИначеЕсли State = EndQuoted Тогда if (Ch = Delimiter) Тогда aList.Add(SB); State = FieldStart; ИначеЕсли (Ch = QuoteChar) Тогда State = ScanQuoted; SB=SB+QuoteChar; StartPos=Inx+1; else ВызватьИсключение("Нет "+Delimiter+ "в позиции ="+Inx ); КонецЕсли; КонецЕсли; Inx=Inx+1; КонецЦикла; // {if we are in the ScanQUoted or GotError state at the end // of the string, there was a problem with a closing quote} if (State = ScanQuoted) Тогда ВызватьИсключение("Нет закрывающей скобки от поз="+Строка(StartPos-1)+ " до конца строки"); КонецЕсли; // {if the current field is not empty, add it to the list} if (State = EndQuoted) Тогда aList.Add(SB); ИначеЕсли (State = ScanField) Тогда CopyCount=Inx-StartPos; aList.Add(Сред(S,StartPos,CopyCount)); КонецЕсли КонецПроцедуры Функция Split(aList) return Split1(aList,",", """"); КонецФункции Функция Split1(aList,Delimiter, QuoteChar) if (( (aList=Неопределено) или (aList.Количество() = 0)) или ((aList.Количество() =1 ) и (СтрДлина(aList[1])=0))) Тогда return QuoteChar+QuoteChar; КонецЕсли; // RStringBuilder Sb= new RStringBuilder(); Sb=""; Для j=0 По aList.ВГраница() Цикл S=aList[j]; Pos=-1; LenStr=СтрДлина(S); if (j>0) Тогда Sb=Sb+Delimiter; КонецЕсли; for i=1 по LenStr Цикл Ch=сред(S,i,1); if (( Ch = Delimiter) или (Ch = QuoteChar) или (КодСимвола(Ch)<33) ) Тогда Sb=Sb+QuoteChar; Sb=Sb+Сред(S,1,i-1); Pos=i; прервать КонецЕсли; КонецЦикла; if (Pos = -1) Тогда Sb=Sb+QuoteChar+S+QuoteChar; // проверить на число можно не добалять для чисел QuoteChar // Sb.Append(S); // Sb.Append(QuoteChar); // проверить на число можно не добалять для чисел QuoteChar else for i = Pos по LenStr Цикл if сред(S,i,1) = QuoteChar Тогда Sb=Sb+Сред(S, Pos, i - Pos + 1); Sb=Sb+QuoteChar; Pos = i + 1; КонецЕсли; КонецЦикла; if (Pos < LenStr) Тогда Sb=Sb+сред(S, Pos, LenStr - Pos+1); КонецЕсли; Sb=Sb+QuoteChar; КонецЕсли; КонецЦикла; return Sb; КонецФункции |
|||
1
Serginio1
13.09.09
✎
13:57
|
B и соответственно использование
Функция СравнитьМассивы(масс1,масс2) Резулт="Массивы Равны"; сравнение=новый СравнениеЗначений; Граница1=Масс1.ВГраница(); Граница2=Масс2.ВГраница(); Если Граница1<>Граница2 Тогда Сообщить("Не равны размерности" +Граница1+"<>"+Граница2); КонецЕсли; Для сч=0 По Мин(Граница1,граница2) Цикл Если Сравнение.Сравнить(Масс1[сч],Масс2[сч])<>0 Тогда Резулт="Массивы не Равны"; Сообщить(" не равны по индексу "+сч); Сообщить(Масс1[сч]+"<>"+Масс2[сч]); КонецЕсли; КонецЦикла; возврат резулт КонецФункции // СравнитьМассивы(масс1,масс2)() Процедура Кнопка1Нажатие(Элемент) Перем Масс2; Масс= новый Массив; Масс.Добавить("п"); Масс.Добавить("прив, "" про ""нк"); Масс.Добавить("прив, """" про ""нк,"); Масс.Добавить("прив, """", про ""нк"""); Стр=Split(Масс); Сообщить(стр); ИзСтрокиСРазделителями(Стр,Масс2); сообщить(СравнитьМассивы(масс,масс2)); КонецПроцедуры Буду благодарен за найденные ошибки. |
|||
2
Fragster
гуру
13.09.09
✎
14:06
|
молодец, возьми с полки пирожок. вообще-то можно в 3 раза меньше кода заюзать
|
|||
3
Serginio1
13.09.09
✎
14:08
|
Спасибо. Можно, но это классический автомат просто и надежно.
|
|||
4
Fragster
гуру
13.09.09
✎
14:10
|
(3) никаких спасибо... какого фига смотришь посимвольно? а если разделителем заюзать больше, чем один символ?
|
|||
5
Fragster
гуру
13.09.09
✎
14:12
|
вот, покури заляпуху в 15 строк:
Книга знаний: Преобразование csv в таблицу значений |
|||
6
Serginio1
13.09.09
✎
14:22
|
(4) Смотри лучше алгоритм.
(5) Пропусти тестовый набор строк Масс.Добавить("п"); Масс.Добавить("прив, "" про ""нк"); Масс.Добавить("прив, """" про ""нк,"); Масс.Добавить("прив, """", про ""нк"""); |
|||
7
Serg_1960
13.09.09
✎
14:25
|
Горе от ума, глянь:
МногоСтрочнаяСтрока = СтрЗаменить(ВашаСтрока, ВашРазделитель, Символы.ПС); Для Индекс = 1 По СтрЧислоСтрок(МногоСтрочнаяСтрока) Цикл Реквизит = СтрПолучитьСтроку(МногоСтрочнаяСтрока, Индекс); ... |
|||
8
Serginio1
13.09.09
✎
14:28
|
(7) Пропусти тестовые строки как в 6
|
|||
9
Fragster
гуру
13.09.09
✎
14:32
|
(6) я же говорю, там заляпуха. но работает сильно быстрее, чем (0)
|
|||
10
Serginio1
13.09.09
✎
14:34
|
(9) А мне надо как правильно и без ВК.
|
|||
11
Fragster
гуру
13.09.09
✎
14:53
|
(10) а где там ВК?
|
|||
12
Serg_1960
13.09.09
✎
15:36
|
(8) А если немножко подумать? Написал как можно проще - детский вариант :)
Кавычка = Симв(34); ЧтоМеняем = Кавычка + Кавычка; НаЧтоМеняем = Кавычка + Символы.ПС + Кавычка; РеквизитыСКавычками = СтрЗаменить(ВашаСтрока, ЧтоМеняем, НаЧтоМеняем); РеквизитыБезКавычек = СтрЗаменить(РеквизитыСКавычками, Кавычка, ""); Для Индекс = 1 По СтрЧислоСтрок(РеквизитыБезКавычек) Цикл ОдинРеквизитИзВашейСтроки = СтрПолучитьСтроку(РеквизитыБезКавычек, Индекс); ... |
|||
13
Serginio1
13.09.09
✎
15:48
|
(11) Где именно? Я про то, что можно написать очень быстрый вариант на компилируемом языке в виде ВК, а медленный но правильный
(12) В 0 нормальный взрослый вариант на автомате Ничего что в строке могут встречаться как разделтели так и кавычки. Твоим методом мы нормальную строку разобъем |
|||
14
Jolly Roger
13.09.09
✎
15:58
|
жость! у гения1с новый ник?
|
|||
15
Serginio1
13.09.09
✎
16:07
|
(14) Если обо мне, то мне до гения очень далеко, но универсален.
|
|||
16
Serginio1
14.09.09
✎
10:34
|
Апну. На C# этот вариант работает на ура, при переписи возможно вкрались ошибки. На первый взгляд не заметные. Проверял на своих реальных данных, ошибок не нашел.
Буду благодарен ели кто протестирует. |
|||
17
Serginio1
14.09.09
✎
12:57
|
апну в последний раз.
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |