RU/2: Форум. Общение пользователей и разработчиков OS/2 (eCS). : Разбиение строки на подстроки


Список сообщений | Написать новое | Ответить на сообщение | Домой Поиск:
Предыдущее сообщение | Следующее сообщение
From : Aleksey Tarasow, 2:5053/57, librexx.ru azimut21.ru azimut64.ru
To : Improver
Subj : Разбиение строки на подстроки

> > Хочу спросить совета у гуру.
> > В подпрограмму передается одна строка (единая строка) в которой может содержаться (или нет) несколько подстрок разделенных запятой. Это все, что знаем о строке. Теперь мне нужно разбить строку на подстроки.
> > Пример строки: DateDo="01.01.2011", DateEnd="25.02.2013", ListCode='Pump1 Pump2', Text="220V ON"
> > Тут все просто, но что делать если "запятая" окажется внутри подстроки?
> > Пример строки: DateDo="01.01.2011", DateEnd="25.02.2013", ListCode='Pump1 Pump2', Text="Что-то не так, как надо"
> > Для этого случая принят алгоритм: находим запятую, если до неё в строке четное количество кавычек, считаем запятая ограничивает подстроку, если нечетно, считаем запятая внутри подстроки.
> > Опять же работало до момента пока не появилась такая строка: wordpos("tae",User)>0
> > Тут вступают в силу ещё и скобки...
> > Сейчас ломаю голову над более менее универсальным алгоритмом разбора строки. Повторим вводные:
> > 1. Разделитель подстрок "запятая".
> > 2. Возможно наличие как минимум следующих ограничителей: "одинарная кавычка", "двойная кавычка", "обратная кавычка", "(", ")", "{", "}"
> > 3. Внутри подстроки есть вероятность встречи ограничителей в любом в любом порядке и без порядке. Например, в качестве куска текста выдернутого из контекста.
> >
> > Кто подскажет алгоритм для Rexx?
>
> Разбиваешь исходную строку при помощи parse value на N подстрок по разделителю "запятая", потом проверяешь количество кавычек, скобок и т.д. в первой подстроке, если оно нечётное, то соединяешь со следующей строкой, и так далее по-порядку обрабатываешь все подстроки...

Так и делаю в настоящий момент, но условий становиться слишком много, и боюсь со временем их число будет только расти. Что сильно усложнит логику.
По этому ищу альтернативные пути решения. В настоящий момент написал скрипт просматривающий строку по символьно. Вот что получились. Все текущие задачи решает, да же есть не большой запас на развитие. Но смущает то, что тратим время на каждый символ.

=====
SubSpace=d2c(01) /* Код для замены пробела */
SubDoubleQuotes=d2c(02) /* Код для замены двойных кавычек */
/*call value Where,"'wordpos('tae',User)>0'"*/

call value Where,'DateDo="01,01,2011", DateEnd="25.02.2013", ListCode='Pump1 Pump2', Text="220V ON"'


ActiveQuotes='' /* Активный тип кавычек, устанавливается при первом использовании */
OpenQuotes=0 /* Количество открытых кавычек */
OpenBracket=0 /* Количество открытых скобок */
rcWhere=''
WhereNew=''
do n=1 to length(Where)
parse value Where with sym 2 Where
select
when sym==ActiveQuotes then do
OpenQuotes=OpenQuotes+1
end
when sym=="'" then do
ActiveQuotes=sym
OpenQuotes=OpenQuotes+1
end
when sym=='"' then do
ActiveQuotes=sym
OpenQuotes=OpenQuotes+1
end
when sym=="(" then OpenBracket=OpenBracket+1
when sym==")" then OpenBracket=OpenBracket-1
when sym==',' then do
if OpenBracket=0 then
if OpenQuotes//2=0 then do
WhereNew=WhereNew' 'translate(strip(rcWhere),SubSpace,' ') /* Заменяем пробелы в условии на код заменитель и добавляем в конец строки команды */
ActiveQuotes='' /* Обнулили Активные кавычки, для того что в следующем блоку можно были использовать кавычки другого типа. */
OpenQuotes=0
rcWhere=''
sym=''
end /* if */
end
Otherwise nop
end /* select */
rcWhere=rcWhere||sym
end n
WhereNew=WhereNew' 'translate(strip(rcWhere),SubSpace,' ') /* Добавляем остаток строки, который не удалось отработать в цикле. */
====

Sat 24 Jan 2015 19:07 Mozilla/5.0 (Windows NT 6.3; WOW64; rv:35.0) Gecko/20100101




Programmed by Dmitri Maximovich, Dmitry I. Platonoff, Eugen Kuleshov.
25.09.99 (c) 1999, RU/2. All rights reserved.
Rewritten by Dmitry Ban. All rights ignored.