Имя: Пароль:
1C
 
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
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
апну в последний раз.