FUNCTION PBMAIN () AS LONG
LOCAL sMain,sField AS STRING
LOCAL x,Rec AS LONG
sMain="%texttest;2332.wew,%data;sdggfr!ggr%sssewe;weewf3"
'
Rec=PARSECOUNT(sMain,"%" 'считаем сколько полей в строке
FOR x = 2 TO rec
sField="%"+PARSE$(sMain,"%",x) ' Выделяем поле
sField=LEFT$(sField, INSTR(-1, sField ,";") 'Обрезаем все что справа от ';'
? sField
NEXT
'
END FUNCTION
REGEXPR:
Scan a string for a matching "wildcard" or regular expression.
сканирует сроку и выделяет то что надо по маске.
возвращает начало найденого и длину.]
задача же поставлена выделить все(если я не знаю что должно стоять между маркерами , каким тогда логическим способом определить что искать?) что стоит между двумя определенными символами, то есть парсинг что я и показал.
 O
position& = position& + length&
REGEXPR sMask IN sMain AT position& TO position&, length&
startPos&=position&
position& = position& + length&
REGEXPR sMask IN sMain AT position& TO position&, length&
endPos&=position&
c$=MID$(sMain,startPos&,endPos&-startPos&
IF c$<>"" THEN ? c$
LOOP UNTIL c$="" OR position&=0
END FUNCTION
но в этом случае если в исходной строке
сбиваеться структура то вся логика гаснет, т.е. если например после первого % убрать ; то все рушиться,
при парсинге же первое поле просто игнорируеться и нормально считывает остальные поля. Можно конечно проверок еще накрутить чтоб не сбивалось, но непонятно зачем увеличивать код изощраясь с регекспом если задача - парсинг
регэкспы как раз для парсинга идеально подходят. Если вдруг структура исходных данных изменится, то переписывать ручной код парсинга будет довольно накладно. А в регэкспе всего лишь заменить регэксп. Да и отлаживать его проще.
Вот кстати, добавил чтобы оно такие вот "неверные" значения игнорировало и искало только верные:
в ПБ регулярные выражения не совсем совместимы
с питоном, ПХП..., и каждый раз возвращаясь к ним через некоторое время хочется назвать эти выражения не как
регулярные а как депрессивные выражения. Не знаю может не разобрался с ними до конца, поэтому использую их для выделения "чего-то" что можно описать, например найти все е-майлы в строке Mask$="[a-z0-9._/+-]+)(@[a-z0-9.-]+)" . Но для выделения данных между делимитерами
ИМХО просче использовать PARSE, и менять рулы ИМХО тоже просче. Вот подправил первый пример:
#COMPILE EXE
#DIM ALL
FUNCTION PBMAIN () AS LONG
LOCAL sMain,sField,startField,endField AS STRING
LOCAL x,Rec AS LONG
sMain="%texttest;2332.wew,%data;sdggfr!ggr%sssewe;weewf3"
startField="%" : endField=";" ' Parsing rules
Rec=PARSECOUNT(sMain,startField) 'ñ÷èòàåì ñêîëüêî ïîëåé â ñòðîêå
FOR x = 2 TO rec
sField=startField+PARSE$(sMain,startField,x) 'Âûäåëÿåì ïîëå (Âñå ÷òî ìåæäó startField="%"
sField=PARSE$(sField,endField,1) 'Îáðåçàåì âñå ÷òî ÷òî ñòîèò ïîñëå ïåðâîãî ';' = endField
? sField
NEXT
? "Stop",64,"Report"
END FUNCTION
Блин, вот он результат парсинга наверху,
если русский символ стоит сразу после апострофа, то получили очень закодированные комментарии :D
Ок, тоже самое но надеюсь вставится нормально
#COMPILE EXE
#DIM ALL
FUNCTION PBMAIN () AS LONG
LOCAL sMain,sField,startField,endField AS STRING
LOCAL x,Rec AS LONG
sMain="%texttest;2332.wew,%data;sdggfr!ggr%sssewe;weewf3"
startField="%" : endField=";" ' Parsing rules
Rec=PARSECOUNT(sMain,startField) ' Считаем количество полей в исходной строке
FOR x = 2 TO rec
' получаем одно поле (все что находится между "%"-signs = startField)
sField=startField+PARSE$(sMain,startField,x)
' Обрезаем мусор после первого ";"-sign = endField
sField=PARSE$(sField,endField,1)
? sField
NEXT
? "Stop",64,"Report"
END FUNCTION
Попробуй вот так. У меня работает во всяком случае для этой строки
#Compile Exe
#Include "WIN32API.INC"
Function PBMain
Dim sMain$, mask$
sMain$="%texttest;2332.wew,%data;sdggfr!ggr%sssewe;weewf3"
mask$="%([^;]*);"
Dim start&,iPos&,iLen&
start&=1
Do
RegExpr mask$ In sMain$ At start& To iPos& , iLen&
MsgBox Mid$(sMain$,iPos&,iLen&
start&=iPos&+iLen&
Loop While iPos&>0
End Function
Вот кстати, добавил чтобы оно такие вот "неверные" значения игнорировало и искало только верные:
%[^;%]+?;
Или ты чего-то перемудрил или в PB такое выражение не работает (а может вообще характерно только для .NET). Само по себе твоё выражение вообще ничего не находит, только если убрать знак вопроса, но тогда функция перестаёт находить последовательности, состоящие только из '%;'.
JMP,
sMask="[%+?;]"
Судя по справке, ты пытаешся найти один любой из указанных в квадратных скобках символов: '%' или '+' или '?' или ';'.
[ ] (square brackets) Identifies a user-defined class of characters, any of which will match: [abc] will match a, b, or c. Only three special metacharacters are recognized within a class definition, the caret ^ for complemented characters, the hyphen - for a range of characters, or one of the following \ backslash escape sequences: \\ \- \] \e \f \n ...