Страница 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
...
Спасибо.