Внешняя компонента Parser. 1C 77.
Скачать ВК Parser (298кб)
Скачать Исходники Delphi ВК Parser (35кб)
На самом деле название компоненты Parser осталось в началах ее создания, и сейчас это скорее набор полезных функций.
В ALS файле описаны не все методы, но большинство.
Создание объекта:
ЗагрузитьВнешнююКомпоненту(''Parser.dll'');
об = СоздатьОбъект(''AddIn.Parser'');"
========= Регулярные выражения (и прочее) ========
реЗагрузитьИзФайла(<Файл>,[<ПрефиксРазмера> = 0])
Загружает разбираемое выражение из файла.
<ПрефиксРазмера> - см.ParseRecursiveListFromFile
реСтрока([<Текст>])
Устанавливает/возвращает строку для разбора. Устанавливать можно из простой строки или из объекта Текст.
реРазмер()
Возвращает размер установленной строки для разбора.
реПозиция([<НоваяПозиция>]),
Устанавливает/возвращает текущую позицию, от которой будет начинаться разбор.
Отсчет начинается от 1.
реРегистрБукв([<Признак>])
Устанавливает/возвращает чувствительность разборщика к прописным/строчным
буквам. Если 1 - различаются, 0 - не различаются.
Должно быть установленым перед компиляцией рег.выражения.
Для разных выражений может устанавливаться различный признак.
реСделатьРЕ(<РегулярноеВыражение>)
Компилирует регулярное выражение и возвращает идентификатор,
по который впоследствии передается при разборе строки.
реВыполнить(<идРегВыраж>)
Выполняет регулярное выражение от непосредственно от
текущей позиции и возвращает 1, если входная строка
от текущей позиции соответствует регулярному выражению. Иначе 0.
Если <идРегВыраж> передана строка, тогда она компилиться,
выполняется и удаляется, без возможности получить найденные подстроки.
Можно использовать для определения наличия, а сам текст когда не важет.
реНайти(<идРегВыраж>, [<отПозиции>])
Ищет строку, соответствующую регулярному выражению от текущей позиции.
Возвращает 0, если не найдена, иначе позицию, в которой была найдена
(от начала строки, а не от текущей позиции).
Так же впоследствии возможно определить, от которой позиции была найдена строка,
с помощью (пар.реПозиция - СтрДлина(пар.реПолучить(<идРегВыраж>, 0)))
<отПозиции> - если указана, тогда ищется от указаной позиции
Если <идРегВыраж> передана строка, тогда она компилиться,
выполняется и удаляется, без возможности получить найденные подстроки.
реПолучить(<идРегВыраж>, <НомСкобки>)
Возвращает строку соответствующую скобке. Нулевая строка
соответствует всему найденому выражению.
реПодстрока(<НачПоз>, <КоличСимв>)
Возвращает строку из обрабатываемой строки от позиции <НачПоз> и размером <КоличСимв>
реСимвол(<Позиция>, [<НовоеЗначение>])
Возвращает/устанавливает символ в хранимой строке.
реКодСимв(<Позиция>, [<НовыйКодСимвола>])
Возвращает/устанавливает в хранимой строке код символа.
реЗаписатьВФайл(<Файл>)
Записывает хранимую строку в файл.
реКодировка()
Опеределяет кодировку хранимой строки, и возвращает в текстовом виде ее название:
cp1251
koi8-r
utf-8
cp866
Спецификация регулярных выражений
(?? ... ) - не сохраняемые скобки (все прочие сохраняются)
(?= ... ) - предпроверка, если равно
(?! ... ) - предпроверка, если не равно
( ... ) - простые скобки
экранирование символов происходим с помощью \ (слэша)
\xFF - вставка символа по коду
\s - предопределенное множество пустого пространства (пробелы, табуляция, перенос строки)
$ - символ окончания текстовой строки (или конец текста или симовлы [#13]#10 (DOS) или #0 (Linux))
^ - символ начала текстовой строки (см. $)
[...] - множества, причем внутри множества возможны:
[^...] - исключающее множество
\xFF - вставка символа по коду
указание интервала символов через "-"
если первым символом множества будет ''-'' тогда, будет считаться просто символом множества, а не интервалом
Примеры регулярных выражений
ЗагрузитьВнешнююКомпоненту("parser.dll");
о = СоздатьОбъект("AddIn.Parser");
о.реСтрока("мой майл v-telnov#yandex.ru");
идРЕ = о.реСделатьРЕ("([-a-zA-Z0-9_.]+)#([-a-zA-Z0-9_.]+)\.([-a-zA-Z0-9_.]+)");
Если о.реНайти(идРЕ) = 0 Тогда
сообщить("Выражение не найдено");
Иначе
сообщить(о.реПолучить(идРЕ, 0));
сообщить(о.реПолучить(идРЕ, 1));
сообщить(о.реПолучить(идРЕ, 2));
сообщить(о.реПолучить(идРЕ, 3));
КонецЕсли;
Как разобрать html теги:
Вот пример, как обработать тег <TD> (для простого случая)
ре_Тег = о.реСделатьРЕ("<TD>((??(?!</TD>)[^\x00])*)</TD>");
Если о.реНайти(ре_Тег) = 1 Тогда
сообщить(о.реПолучить(ре_Тег, 1));
КонецЕсли;
В результате будет выведено весь текст, содержащийся между тегами <TD> и </TD>
Разное вспомогательное
мд5(<Строка>)
Обрабатывает строку по алгоритму MD5 и результат конвертирует
в строку шестнадцатиричного представления MD5. (32 символа 0..9, A..F)
md5_file(<НазвФайла>)
Обрабатывает файл по алгоритму MD5 и результат конвертирует в строку
шестнадцатиричного представления MD5. (32 символа 0..9, A..F)
рнд()
Возвращает случайное число в интервале 0 <= val < 1
list(<Строка>, [<Разделитель>=","], [<РезСЗ>=""])
Возвращает список значений, состоящий из строк, полученных
путем разбития <Строка> на подстроки через <Разделитель>. <Разделитель> может
быть любой длины. Пустые строки не добавляются. У строк отсекаются
пробельные символы слева и справа. Если передан <РезСЗ>, тогда значения
будут добавляться в него, без предварительной очистки.
ЗначениеВСтрокуВнутр(<Значение>)
Если пытаться конвертировать стандартной функцией из значения, которое взято из
РЕКВИЗИТА НЕОПРЕДЕЛЕННОГО ТИПА ИЛИ ВИДА, тогда результат будет
отличаться от результат, если бы значение было определенного типа и вида
(кто знает, тот поймет, или поэксперементируйте). Для получения стандартного
вида обычно требует выполнения метода ТекущийЭлемент() или ТекущийДокумент(),
что есть затраты по времени, особенно на сетевых базах (ну или делать алгоритм
синтаксического разбора результата на 1С). Данный метод исправляет этоту
особенность, простой текстовой конвертацией в представление определенного типа-вида.
СтрРазделить(<СтрИсходная>, <Разделитель>, <СтрПрав>)
Разделяет строку по подстроке. Возвращает левую часть и в параметре правую часть.
ЗагрузитьИнетСтраницу(
<URL>,
<ФайлКудаСохранить>,
<МаксимальныйГрузимыйРазмер>=-1,
<ВремяОжидания> = 600*1000)
<URL> д.б. обязательно абсолютного типа, с указанием протокола (http, ftp), т.е.
http://www.rambler.ru
Если <МаксимальныйГрузимыйРазмер> = 0, тогда идет только проверка наличия файла. Если = -1, грузиться весь.
<ВремяОжидания> - если выполнение превысит время, тогда процедура завершится с ошибкой истекло время выполнения
ОтправитьПисьмо(
Host,
Login,
Password,
From,
To,
Subject,
TextBody,
ФайлДляОтправки = "")
Если письмо отправлено, возвращает пустую строку, иначе возвращает описание ошибки. Отправка идет через порт
2525.
Пример:
ОтправитьПисьмо("smtp.yandex.ru", "telnov-vs", "myPass", "Виктор <telnov-vs@yandex.ru>",
"TempMyBox <telnov-vs@yandex.ru>", "test", "test send mail")
в полях From и To можно указать просто адрес, без угловых скобок, если не требуется
указывать имени, чей почтовый ящик.
popConnect
попПодключиться(Host,User,Password)
При удачном подключении возвращает количество писем в ящике.
попПодключиться("pop.yandex.ru", "telnov-vs", "my_pass");
popGetSubject
попПолучитьТему(НомерПисьма)
Возращает заголовок письма.
popGetAttachment
попЗагрузитьФайл(НомерПисьма, СохранитьВФайл)
Сохраняет прикрепленный к письму файл в файл на диске.
popDeleteMail
попУдалитьПисьмо(НомерПисьма)
popDisconnect
попОтключиться()
Методов для получения тела письма на данный момент не написаны
======== Анализ форматов 1С ==========
ValueTextConst(<Строка>,[<ПризнакПростаяСтрока>=0])
конвертирует текстовые константы, формата 1С, в их текстовое значение.
Для примера, строка <"Это строка, "" - это одинарная ковычка">, будет сконвертированна в
<Это строка, " - это одинарная ковычка>. Распознает перенос на другую строку
через символ |. Если <ПростаяСтрока> = 1, тогда символ | не воспринимается.
ParserRecursiveList(<Строка>, [<РезСЗ>=""])
Разбирает строку <Строка>, на рекурсивный (вложенный) список значений.
Разделителем элементов является запятая, ограничением вложенности - фигурные скобки.
Значения не запятые и не фигурные скобки попадают в рез.список как есть.
Для дальнейшей работы с этими значениями, их следует конвертировать
функцией ValueTextConst. Если передан <РезСЗ>, догда значения
добавляются в него, без предварительной очистки. Этот формат
используется 1С для сохранения списков и прочих значений в строки,
также таким образом сохранена структура ALS файла.
ParserRecursiveListFromFile(
<Файл>,
[<РезСЗ>=""],
[<ПрефиксРазмера>=1],
[<СоздатьВложенный>=1])
Разбирает список из файла, по принципу, как ParserRecursiveList.
НО, если <СоздатьВложенный> = 0, тогда разбор ограничется только разбором
на отдельные лексемы, без создания вложенного списка и без контроля
парности скобок. В рез.список будет также помещены символы фигурных
скобок и запятых. Если параметр <ПрефиксРазмера> = 1, тогда будет считаться,
что файл имеет префикс размера, такой, как используется в файла MD и ERT
(правильно понимает ЛЮБОЙ префикс размера). Этой функцией удобно
пользоваться для разбора файла-результата от копоненты Compound.
ParserLex(<ПрогТекст>,[<ТипТекста>=0],[<РезСЗ>=''''])
Разбирает программный модуль 1С на отдельные составляющие лексемы.
Если <ТипТекста> = 1, тогда считается, что передана формула,
содержащая строку форматирования - символ #, как в функции
Шаблон или ячейках печатной таблицы, и все, что располагается
за символом # будет опущено.
ParserLexFromFile(<Файл>, [<РезТЗ>=""])
Разбирает программный модуль 1С на отдельные составляющие лексемы,
исходные данные берет из файла, результат помещает в ТаблицуЗначений
с колонками (Lex,NumLine,NumLex). Где Lex - значение лексемы, NumLine
- номер строки программы, NumLex - номер лексемы (дублирует НомерСтроки).
Если передана <РезТЗ>, тогда результат будет помещаться в нее,
без предварительно очистки, НО ее формат должен заранее соответствовать указаному выше.
ParserTemplate(<Шаблон>, <ВозвратПризнакаОшибки>)
Конвертирует выражение, как для функции Шаблон
(или ячейка печ.таблицы типа шаблон) в простое
выражение 1С. Т.е. <а + б равно [а + б]> будет сконвертированно
в <"а + б равно "+(а+б)>. При этом, если шаблон использует
форматирование, тогда <а+б равно [а+б #Ч20.2]> сконвертируется в
<"а+б равно "+Формат(а+б,"Ч20.2")> Эту функцию можно использовать для
предварительного разбора, дабы потом разобрать через функцию ParserLex.
ParserMXL(<Файл>)
разбирает файл формата MXL, вытягивает из него все тексты,
формулы, шаблоны, расшифровки и возвращает результат в виде
СписокЗначений, формат значений которого таковой (в виде строк):
<Text:<...>> - текстовое значение ячейки
<Expression:<...>> - значения выражений и расшифровок
<Template:<...>> - значения шаблонов
<Error: описание> - при разборе возникла ошибка.
Одно значение списка - одна строка в печ.таблице.
В данном разборщике разбираются большинство внутренних форматов MXL,
но запросто могут существовать типы данных, не учтенных в нем.
В частности, я не проверял его на новых печ.таблицах, где используется наклонный текст.