Страница 1 из 3
					
				Сплит строки по пробелу или табуляции
				Добавлено: 15 Июнь 2017, 13:52
				 Admin
				Строка может быть разбита пробелами и/или табами.
Последовательно может быть более одного пробела и таба.
Код: Выделить всё
aaa bbbbb    ccc  ddd<9>eee<9><9><9><9>fff 666     9999
Нужно получить все слова. 
В плане обработка пары тысяч строк. Желательно быстро. 
Предложите что то оптимальное.
Спасибо.
P.S. На php это мегабыстро
 
			 
			
					
				Сплит строки по пробелу или табуляции
				Добавлено: 15 Июнь 2017, 15:19
				 Yufil
				А что там сложного?  Завести переменные для текущей позиции, текущего статуса, начала подстроки 
Пробежаться по строке и в зависимости от состояния и встреченного символа устанавливать новое состояние и выделять подстроку. 
Подстроки складываются в очередь ( по вкусу, позиция + длина, &String на вырезку или копированием подстроки)  
Что-то навскидку у себя не раскопаю, хотя и есть...
			 
			
					
				Сплит строки по пробелу или табуляции
				Добавлено: 15 Июнь 2017, 16:03
				 Admin
				Да ничего сложно. Думал у кого то есть "супер" оптимизированный сплит.
			 
			
					
				Сплит строки по пробелу или табуляции
				Добавлено: 15 Июнь 2017, 16:17
				 Admin
				Я как то так накатал:
Код: Выделить всё
SplitClass.Init                       PROCEDURE(STRING Text)
Cnt                                   LONG
TextLen                               LONG  
LoopInWord                            BYTE
StartWord                             LONG
WordSize                              LONG
  CODE 
  TextLen = LEN(CLIP(Text))
  LOOP Cnt = 1 TO TextLen
    ! если пробел или таб
    IF Text[Cnt] = ' ' OR Text[Cnt] = CHR(9)
      IF LoopInWord = TRUE  
        LoopInWord = FALSE 
        WordSize = Cnt - StartWord
        !debug.Show(SUB(Text, StartWord, WordSize))
      END
    ELSE   
      IF LoopInWord = FALSE 
        LoopInWord = TRUE 
        StartWord = Cnt
      END
    END
  END
  IF LoopInWord = TRUE  
    WordSize = Cnt - StartWord
    !debug.Show(SUB(Text, StartWord, WordSize))
  END
 
			 
			
					
				Сплит строки по пробелу или табуляции
				Добавлено: 15 Июнь 2017, 16:18
				 Yufil
				Примерно так, правда подстроки не складируются. Len(Clip(text)) вызовет копирование текста, если текст реально длинный - нехорошо... 
Тут главная оптимизация - не менять исходную строку и не копировать подстроки. 
Например, складывать подстроки в очередь 
StrQ   Queue
Str     &String 
         End
.... 
StrQ.str  &= S[ i# : j# ]  ; Add(strQ) 
Вырезка является ссылкой на строку, можно её хранить в &String, не меняя исходную строку 
Ну и, разумеется, не пользовать Instring и Sub, с копированием исходной строки...
			 
			
					
				Сплит строки по пробелу или табуляции
				Добавлено: 15 Июнь 2017, 16:27
				 kreator
				Строки в SQL? Тогда смотрим - 
https://msdn.microsoft.com/ru-ru/library/mt684588.aspx. Хотя функция новая, Ваш сервак может не поддерживать.
 
			 
			
					
				Сплит строки по пробелу или табуляции
				Добавлено: 15 Июнь 2017, 16:53
				 Ал
				Admin писал(а): 15 Июнь 2017, 16:17
Я как то так накатал:...
 
Text =  '       qwqwewe  qwewewe...' 

 
			 
			
					
				Сплит строки по пробелу или табуляции
				Добавлено: 15 Июнь 2017, 17:02
				 Admin
				Ал писал(а): 15 Июнь 2017, 16:53Text = ' qwqwewe qwewewe...' 
 
Что не так с этой строкой?
Мне нужно парсить такое. Это логи радиолюбительских соревнований.
Формат может немного различаться. В каждой строке форматирование может быть от руки...
Код: Выделить всё
QSO:    145 FM  2016-09-24  1300    RW0C    59 001  RD0CD   59 001
QSO:    145 FM  2016-09-24  1301    RW0C    59 002  UA0CJH  59 001
QSO:    145 FM  2016-09-24  1302    RW0C    59 003  R0CBG   59 003
QSO:    145 FM  2016-09-24  1302    RW0C    59 004  RM0C    59 002
QSO:    145 FM  2016-09-24  1303    RW0C    59 005  R0CBK   58 001
QSO:    145 FM  2016-09-24  1304    RW0C    59 006  RY0CAC  59 002
QSO:    145 FM  2016-09-24  1308    RW0C    59 007  RA0CGY  59 007
QSO:    145 FM  2016-09-24  1309    RW0C    59 008  R0CBM   59 006
QSO:    145 FM  2016-09-24  1310    RW0C    59 009  RN0CW   59 003
QSO:    145 FM  2016-09-24  1312    RW0C    59 010  R0CBK   59 003
QSO:    145 FM  2016-09-24  1314    RW0C    59 011  RZ0CWN  59 003
QSO:    145 FM  2016-09-24  1316    RW0C    59 012  R0CQ    59 004
QSO:    145 FM  2016-09-24  1316    RW0C    59 013  R0CBP   59 008
QSO:    145 FM  2016-09-24  1322    RW0C    59 014  R0CBO   59 007
QSO:    145 FM  2016-09-24  1331    RW0C    59 015  RY0CAC  59 016
QSO:    145 FM  2016-09-24  1332    RW0C    59 016  UA0CJH  59 014
QSO:    145 FM  2016-09-24  1332    RW0C    59 017  RD0CD   59 011
QSO:    145 FM  2016-09-24  1333    RW0C    59 018  RZ0CWN  59 012
QSO:    145 FM  2016-09-24  1333    RW0C    59 019  RA0CGY  59 017
QSO:    145 FM  2016-09-24  1335    RW0C    59 020  R0CBG   59 023
QSO:    145 FM  2016-09-24  1335    RW0C    59 021  R0CBM   59 012
QSO:    145 FM  2016-09-24  1336    RW0C    59 022  RN0CW   59 008
QSO:    145 FM  2016-09-24  1337    RW0C    59 023  RM0C    59 015
QSO:    145 FM  2016-09-24  1338    RW0C    59 024  R0CQ    59 011
QSO:    145 FM  2016-09-24  1340    RW0C    59 025  R0CBP   59 017
QSO:    145 FM  2016-09-24  1340    RW0C    59 026  R0CBO   59 018
QSO:    145 FM  2016-09-24  1400    RW0C    59 027  R0CBM   59 019
QSO:    145 FM  2016-09-24  1400    RW0C    59 028  R0CBP   59 025
QSO:    145 FM  2016-09-24  1401    RW0C    59 029  UA0CJH  59 027
QSO:    145 FM  2016-09-24  1403    RW0C    59 030  RY0CAC  59 032
QSO:    145 FM  2016-09-24  1403    RW0C    59 031  RM0C    59 025
QSO:    145 FM  2016-09-24  1404    RW0C    59 032  RD0CD   59 023
QSO:    145 FM  2016-09-24  1404    RW0C    59 033  RA0CGY  59 028
QSO:    145 FM  2016-09-24  1408    RW0C    59 034  RZ0CWN  59 029
QSO:    145 FM  2016-09-24  1421    RW0C    59 035  R0CBG   59 044
QSO:    145 FM  2016-09-24  1422    RW0C    59 036  R0CQ    59 024
QSO:    145 FM  2016-09-24  1423    RW0C    59 037  UA0CKW  59 010
QSO:    145 FM  2016-09-24  1424    RW0C    59 038  R0CBO   59 030
QSO:    145 FM  2016-09-24  1430    RW0C    59 039  R0CBM   59 028
QSO:    145 FM  2016-09-24  1430    RW0C    59 040  R0CBP   59 038
QSO:    145 FM  2016-09-24  1432    RW0C    59 041  RM0C    59 036
QSO:    145 FM  2016-09-24  1433    RW0C    59 042  R0CBO   59 034
QSO:    145 FM  2016-09-24  1434    RW0C    59 043  R0CBG   59 051
QSO:    145 FM  2016-09-24  1434    RW0C    59 044  UA0CJH  59 042
QSO:    145 FM  2016-09-24  1437    RW0C    59 045  RY0CAC  59 048
QSO:    145 FM  2016-09-24  1438    RW0C    59 046  R0CQ    59 029
QSO:    145 FM  2016-09-24  1439    RW0C    59 047  RA0CGY  59 046
QSO:    145 FM  2016-09-24  1453    RW0C    59 048  RD0CD   59 040
QSO:    145 FM  2016-09-24  1459    RW0C    59 049  UA0CC   59 006
QSO:    433 FM  2016-09-24  1323    RW0C    59 001  R0CBM   59 005
QSO:    433 FM  2016-09-24  1324    RW0C    59 002  R0CBO   59 005
QSO:    433 FM  2016-09-24  1324    RW0C    59 003  RY0CAC  59 006
QSO:    433 FM  2016-09-24  1326    RW0C    59 004  R0CQ    59 004
QSO:    433 FM  2016-09-24  1328    RW0C    59 005  RN0CW   59 002
QSO:    433 FM  2016-09-24  1350    RW0C    59 006  R0CBM   59 012
QSO:    433 FM  2016-09-24  1351    RW0C    59 007  RY0CAC  59 012
QSO:    433 FM  2016-09-24  1353    RW0C    59 008  R0CQ    59 007
QSO:    433 FM  2016-09-24  1412    RW0C    59 009  RN0CW   59 004
QSO:    433 FM  2016-09-24  1413    RW0C    59 010  RY0CAC  59 014
QSO:    433 FM  2016-09-24  1414    RW0C    59 011  R0CBM   59 015
QSO:    433 FM  2016-09-24  1416    RW0C    59 012  R0CBO   59 010
QSO:    433 FM  2016-09-24  1445    RW0C    59 013  R0CBM   59 026
QSO:    433 FM  2016-09-24  1445    RW0C    59 014  RY0CAC  59 025
QSO:    433 FM  2016-09-24  1446    RW0C    59 015  R0CBO   59 019
QSO:    433 FM  2016-09-24  1447    RW0C    59 016  R0CQ    59 015
QSO:    433 FM  2016-09-24  1449    RW0C    59 017  RT0C    59 014
QSO:    433 FM  2016-09-24  1450    RW0C    59 018  UA0CC   59 001
 
			 
			
					
				Сплит строки по пробелу или табуляции
				Добавлено: 15 Июнь 2017, 17:03
				 Admin
				Yufil писал(а): 15 Июнь 2017, 16:18StrQ.str &= S[ i# : j# ] ; Add(strQ) 
Вырезка является ссылкой на строку, можно её хранить в &String, не меняя исходную строку 
Ну и, разумеется, не пользовать Instring и Sub, с копированием исходной строки...
 
Отличный совет. Спасибо
 
			 
			
					
				Сплит строки по пробелу или табуляции
				Добавлено: 15 Июнь 2017, 17:03
				 Дед Пахом
				Всегда думал, что соревнования радиолюбителей это кто дальше бросит приёмник 

 
			 
			
					
				Сплит строки по пробелу или табуляции
				Добавлено: 15 Июнь 2017, 17:33
				 Admin
				Admin писал(а): 15 Июнь 2017, 17:03StrQ.str &= S[ i# : j# ]
 
Без создания переменной не получается. Орет на двойное освобождение памяти.
Сделал так.
Код: Выделить всё
SplitClass.Construct                  PROCEDURE
  CODE
  SELF.Items &= NEW ItemsQueue
  
SplitClass.Destruct                   PROCEDURE
  CODE
  SELF.ClearAll
  DISPOSE(SELF.Items)
  
SplitClass.Init                       PROCEDURE(STRING Text)
Result                                &STRING  
Cnt                                   LONG
TextLen                               LONG  
LoopInWord                            BYTE
StartWord                             LONG
  CODE 
  TextLen = LEN(CLIP(Text))
  LOOP Cnt = 1 TO TextLen
    ! если пробел или таб
    IF Text[Cnt] = ' ' OR Text[Cnt] = CHR(9)
      IF LoopInWord = TRUE  
        LoopInWord = FALSE 
        Result &= NEW STRING(Cnt - StartWord)
        Result = Text[StartWord : Cnt]
        SELF.Add(Result)
      END
    ELSE   
      IF LoopInWord = FALSE 
        LoopInWord = TRUE 
        StartWord = Cnt
      END
    END
  END
  IF LoopInWord = TRUE  
    Result &= NEW STRING(Cnt - StartWord)
    Result = Text[StartWord : Cnt]
    SELF.Add(Result)
  END
SplitClass.Add                        PROCEDURE(*STRING Text)
  CODE   
  SELF.Items.Item &= Text   
  ADD(SELF.Items)
  
SplitClass.Count                      PROCEDURE()!,LONG
  CODE                                                       
  RETURN RECORDS(SELF.Items)
SplitClass.Get                        PROCEDURE(LONG Number)!,STRING
  CODE           
  GET(SELF.Items, Number)
  RETURN SELF.Items.Item
  
SplitClass.ClearAll                   PROCEDURE  
Cnt                                   LONG
  CODE
  LOOP Cnt = 1 TO RECORDS(SELF.Items)
    GET(SELF.Items, Cnt)
    DISPOSE(SELF.Items.Item)
  END                          
 
			 
			
					
				Сплит строки по пробелу или табуляции
				Добавлено: 15 Июнь 2017, 18:49
				 Yufil
				Насчёт двойного освобождения памяти - очень интересно... Может быть, надо очистить ссылку перед присвоением значения... 
Код: Выделить всё
Result &= NEW STRING(Cnt - StartWord)
Result = Text[StartWord : Cnt]
Почему-то мне хочется ещё байтик добавить к полю Result ...
 
			 
			
					
				Сплит строки по пробелу или табуляции
				Добавлено: 15 Июнь 2017, 18:52
				 Ал
				Admin писал(а): 15 Июнь 2017, 17:02
Ал писал(а): 15 Июнь 2017, 16:53Text = ' qwqwewe qwewewe...' 
 
Что не так с этой строкой?
Мне нужно парсить такое. Это логи радиолюбительских соревнований.
Формат может немного различаться. В каждой строке форматирование может быть от руки...
Код: Выделить всё
QSO:    145 FM  2016-09-24  1300    RW0C    59 001  RD0CD   59 001
QSO:    145 FM  2016-09-24  1301    RW0C    59 002  UA0CJH  59 001
QSO:    145 FM  2016-09-24  1302    RW0C    59 003  R0CBG   59 003
QSO:    145 FM  2016-09-24  1302    RW0C    59 004  RM0C    59 002
QSO:    145 FM  2016-09-24  1303    RW0C    59 005  R0CBK   58 001
QSO:    145 FM  2016-09-24  1304    RW0C    59 006  RY0CAC  59 002
QSO:    145 FM  2016-09-24  1308    RW0C    59 007  RA0CGY  59 007
QSO:    145 FM  2016-09-24  1309    RW0C    59 008  R0CBM   59 006
QSO:    145 FM  2016-09-24  1310    RW0C    59 009  RN0CW   59 003
QSO:    145 FM  2016-09-24  1312    RW0C    59 010  R0CBK   59 003
QSO:    145 FM  2016-09-24  1314    RW0C    59 011  RZ0CWN  59 003
QSO:    145 FM  2016-09-24  1316    RW0C    59 012  R0CQ    59 004
QSO:    145 FM  2016-09-24  1316    RW0C    59 013  R0CBP   59 008
QSO:    145 FM  2016-09-24  1322    RW0C    59 014  R0CBO   59 007
QSO:    145 FM  2016-09-24  1331    RW0C    59 015  RY0CAC  59 016
QSO:    145 FM  2016-09-24  1332    RW0C    59 016  UA0CJH  59 014
QSO:    145 FM  2016-09-24  1332    RW0C    59 017  RD0CD   59 011
QSO:    145 FM  2016-09-24  1333    RW0C    59 018  RZ0CWN  59 012
QSO:    145 FM  2016-09-24  1333    RW0C    59 019  RA0CGY  59 017
QSO:    145 FM  2016-09-24  1335    RW0C    59 020  R0CBG   59 023
QSO:    145 FM  2016-09-24  1335    RW0C    59 021  R0CBM   59 012
QSO:    145 FM  2016-09-24  1336    RW0C    59 022  RN0CW   59 008
QSO:    145 FM  2016-09-24  1337    RW0C    59 023  RM0C    59 015
QSO:    145 FM  2016-09-24  1338    RW0C    59 024  R0CQ    59 011
QSO:    145 FM  2016-09-24  1340    RW0C    59 025  R0CBP   59 017
QSO:    145 FM  2016-09-24  1340    RW0C    59 026  R0CBO   59 018
QSO:    145 FM  2016-09-24  1400    RW0C    59 027  R0CBM   59 019
QSO:    145 FM  2016-09-24  1400    RW0C    59 028  R0CBP   59 025
QSO:    145 FM  2016-09-24  1401    RW0C    59 029  UA0CJH  59 027
QSO:    145 FM  2016-09-24  1403    RW0C    59 030  RY0CAC  59 032
QSO:    145 FM  2016-09-24  1403    RW0C    59 031  RM0C    59 025
QSO:    145 FM  2016-09-24  1404    RW0C    59 032  RD0CD   59 023
QSO:    145 FM  2016-09-24  1404    RW0C    59 033  RA0CGY  59 028
QSO:    145 FM  2016-09-24  1408    RW0C    59 034  RZ0CWN  59 029
QSO:    145 FM  2016-09-24  1421    RW0C    59 035  R0CBG   59 044
QSO:    145 FM  2016-09-24  1422    RW0C    59 036  R0CQ    59 024
QSO:    145 FM  2016-09-24  1423    RW0C    59 037  UA0CKW  59 010
QSO:    145 FM  2016-09-24  1424    RW0C    59 038  R0CBO   59 030
QSO:    145 FM  2016-09-24  1430    RW0C    59 039  R0CBM   59 028
QSO:    145 FM  2016-09-24  1430    RW0C    59 040  R0CBP   59 038
QSO:    145 FM  2016-09-24  1432    RW0C    59 041  RM0C    59 036
QSO:    145 FM  2016-09-24  1433    RW0C    59 042  R0CBO   59 034
QSO:    145 FM  2016-09-24  1434    RW0C    59 043  R0CBG   59 051
QSO:    145 FM  2016-09-24  1434    RW0C    59 044  UA0CJH  59 042
QSO:    145 FM  2016-09-24  1437    RW0C    59 045  RY0CAC  59 048
QSO:    145 FM  2016-09-24  1438    RW0C    59 046  R0CQ    59 029
QSO:    145 FM  2016-09-24  1439    RW0C    59 047  RA0CGY  59 046
QSO:    145 FM  2016-09-24  1453    RW0C    59 048  RD0CD   59 040
QSO:    145 FM  2016-09-24  1459    RW0C    59 049  UA0CC   59 006
QSO:    433 FM  2016-09-24  1323    RW0C    59 001  R0CBM   59 005
QSO:    433 FM  2016-09-24  1324    RW0C    59 002  R0CBO   59 005
QSO:    433 FM  2016-09-24  1324    RW0C    59 003  RY0CAC  59 006
QSO:    433 FM  2016-09-24  1326    RW0C    59 004  R0CQ    59 004
QSO:    433 FM  2016-09-24  1328    RW0C    59 005  RN0CW   59 002
QSO:    433 FM  2016-09-24  1350    RW0C    59 006  R0CBM   59 012
QSO:    433 FM  2016-09-24  1351    RW0C    59 007  RY0CAC  59 012
QSO:    433 FM  2016-09-24  1353    RW0C    59 008  R0CQ    59 007
QSO:    433 FM  2016-09-24  1412    RW0C    59 009  RN0CW   59 004
QSO:    433 FM  2016-09-24  1413    RW0C    59 010  RY0CAC  59 014
QSO:    433 FM  2016-09-24  1414    RW0C    59 011  R0CBM   59 015
QSO:    433 FM  2016-09-24  1416    RW0C    59 012  R0CBO   59 010
QSO:    433 FM  2016-09-24  1445    RW0C    59 013  R0CBM   59 026
QSO:    433 FM  2016-09-24  1445    RW0C    59 014  RY0CAC  59 025
QSO:    433 FM  2016-09-24  1446    RW0C    59 015  R0CBO   59 019
QSO:    433 FM  2016-09-24  1447    RW0C    59 016  R0CQ    59 015
QSO:    433 FM  2016-09-24  1449    RW0C    59 017  RT0C    59 014
QSO:    433 FM  2016-09-24  1450    RW0C    59 018  UA0CC   59 001
 
 
хм..
форматы могут быть совсем любые? т.е. этот текст надо читать напрямую, нельзя например через excel/calc перегнать например в csv и  потом читать?
 
			 
			
					
				Сплит строки по пробелу или табуляции
				Добавлено: 15 Июнь 2017, 19:08
				 Admin
				Ал писал(а): 15 Июнь 2017, 18:52форматы могут быть совсем любые? т.е. этот текст надо читать напрямую, нельзя например через excel/calc перегнать например в csv и потом читать?
 
Да нет. Уже все работает и парсится.
 
			 
			
					
				Сплит строки по пробелу или табуляции
				Добавлено: 15 Июнь 2017, 19:10
				 Admin
				Yufil писал(а): 15 Июнь 2017, 18:49Насчёт двойного освобождения памяти - очень интересно... Может быть, надо очистить ссылку перед присвоением значения...
 
Завтра посмотрю. А то 2 ночи 

Еще вопрос. Как по такой очереди GET по полю делать, что то не работает. Перебирать?
Код: Выделить всё
ItemsQueue            QUEUE,TYPE
Item                    &STRING
                      END       
                      
SplitClass            CLASS,MODULE('SplitClass.clw'),TYPE,LINK('SplitClass.clw',_ABCLinkMode_)
Items                   &ItemsQueue
...
 Спасибо.