Простые регулярные выражения




Принцип обмена данными из 1С с сайтом (на MySQL) и выдачи (публикации) этих данных по запросу.
PHP-Скрипт автоматической загрузки данных из файла данных в формате CSV в базу данных сайта работающего на WordPress.

В продолжение моей темы: 1С:Альфа-Авто Автосалон Автосервис: обмен с сайтом.
С помощью данного скрипта можно загружать в автоматическом режиме, по расписанию, данные сервисных книжек (ремонтов авто) из 1С:Альфа-Авто Автосалон Автосервис.
Также можно загружать данные в ручном режиме: для этого делается скрытая страница, где размещается специальная кнопка.
Комментарии размещенные внутри скрипта разъяснят логику и порядок действия.
Комментарии с "/////    echo" использовались для отладки.
Дополнительно создана таблица для журналирования результатов загрузки данных.
Скрипт включает в себя защиту от SQL инъекций (думаю безопасность соблюдена в полной мере).
В кратце:
1. Пишется скрипт, который запускает этот.
2. Создается регламентное задание в WordPress, по которому запускается скрипт из п.1. 
3. Этот скрипт осуществляет проверку на существование файла обмена в папке.
4. Если данные не новые, загрузка не производится.
5. Если данные новые, очищается таблица сервисных книжек.
6. Загружаются новые данные.

Собственно сам скрипт:

<?php // Полная загрузка сервисных книжек, создан 2026-01-05 12:44:55

global $wpdb2;
global $failure;
global $file_hist;

/////  echo '<H2><b>Старт загрузки</b></H2><br>';

$failure=FALSE;
//подключаемся к базе
$wpdb2 = include_once 'connection.php'; ; // подключаемся к MySQL
// если не удалось подключиться, и нужно оборвать PHP с сообщением об этой ошибке
if (!empty($wpdb2->error))
{
/////   echo '<H2><b>Ошибка подключения к БД, завершение.</b></H2><br>';
$failure=TRUE;
wp_die( $wpdb2->error );
}

$m_size_file=0;
$m_mtime_file=0;
$m_comment='';
/////проверка существования файлов выгрузки из 1С
////файл выгрузки сервисных книжек
$file_hist = ABSPATH.'/_1c_alfa_exchange/AA_hist.csv';
if (!file_exists($file_hist))
{
/////   echo '<H2><b>Файл обмена с сервисными книжками не существует.</b></H2><br>';
$m_comment='Файл обмена с сервисными книжками не существует';
$failure=TRUE;
}

/////инициируем таблицу лога
/////если не существует файла то возврат и ничего не делаем
if ($failure){
///включает защиту от SQL инъекций и данные можно передавать как есть, например: $_GET['foo']
/////   echo '<H2><b>Попытка вставить запись в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>$m_comment));
wp_die();
/////    echo '<H2><b>Возврат в начало.</b></H2><br>';
return $failure;
}
/////проверка лога загрузки, что бы не загружать тоже самое
$masiv_data_file=stat($file_hist);   ////передаем в массив свойство файла
$m_size_file=$masiv_data_file[7];    ////получаем размер файла
$m_mtime_file=$masiv_data_file[9];   ////получаем дату модификации файла
////создаем запрос на получение последней удачной загрузки
////выбираем по штампу времени создания (редактирования) файла загрузки AA_hist.csv, $m_mtime_file

/////   echo '<H2><b>Размер файла: '.$m_size_file.'</b></H2><br>';
/////   echo '<H2><b>Штамп времени файла: '.$m_mtime_file.'</b></H2><br>';
/////   echo '<H2><b>Формирование запроса на выборку из лога</b></H2><br>';
////препарируем запрос
$text_zaprosa=$wpdb2->prepare("SELECT * FROM `vin_logs` WHERE `last_mtime_upload` = %s", $m_mtime_file);
$results=$wpdb2->get_results($text_zaprosa);

if ($results)
{   foreach ( $results as $r)
{
////если штамп времени и размер файла совпадают, возврат
if (($r->last_mtime_upload==$m_mtime_file) && ($r->last_size_upload==$m_size_file))
{////echo '<H2><b>Возврат в начало, т.к. найдена запись в логе.</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>'Загрузка отменена, новых данных нет, т.к. найдена запись в логе.'));
wp_die();
return $failure;
}
}
}
////если данные новые, пишем в лог запись о начале загрузки
/////echo '<H2><b>Попытка вставить запись о начале загрузки в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>0, 'last_size_upload'=>$m_size_file, 'comment'=>'Начало загрузки'));

////очищаем таблицу
$clear_tbl_zap=$wpdb2->prepare("TRUNCATE TABLE %s", 'vin_history');
$clear_tbl_zap_repl=str_replace("'","`",$clear_tbl_zap);
$results=$wpdb2->query($clear_tbl_zap_repl);
/////   echo '<H2><b>Очистка таблицы сервисных книжек</b></H2><br>';
if (empty($results))
{
/////   echo '<H2><b>Ошибка очистки таблицы книжек, завершение.</b></H2><br>';
//// если очистка не удалась, возврат
$failure=TRUE;
wp_die();
return $failure;
}

////загружаем данные
$table='vin_history';         // Имя таблицы для импорта
//$file_hist Имя CSV файла, откуда берется информация     // (путь от корня web-сервера)
$delim=';';          // Разделитель полей в CSV файле
$enclosed='"';      // Кавычки для содержимого полей
$escaped='\

30 Comments

  1. tormozit

    Это точно для 1сников? =)

    Уж очень сложно и неудобно.

    Reply ↓
  2. vasilev2015

    (1) Здравствуйте, Сергей ! Когда я смотрел другие статьи про регулярные выражения, где упор делается на использование perl, у меня возникал тот же вопрос. Постарался упростить ))).

    Регулярные выражения примечательны тем, что позволяют парсить файлы технологического журнала общим объемом порядка 100 Гигабайт за время порядка 5 минут. Других таких инструментов нет. ЦУП медленнее на порядки.

    P.S. Пользуюсь инструментами разработчика каждый день. Спасибо Вам.

    Reply ↓
  3. tormozit

    (2) Кажется обычно более разумно настроить фильтр записи журнала (logcfg.xml), чтобы он собирал то, что нужно. А не собирать в 10-100 раз больше логовов, чем нужно, неоправдано нагружая сервер и вынуждая себя пользоваться в разы менее удобными инструментами. В анализе техножурнала (ИР) непосредственно при чтении логов сейчас доступен только отбор по дате и он уже в большинстве случаев в разы ускоряет загрузку логов. Планирую туда же добавить фильтр по типу события (на этапе чтения). Он позволит еще ускорить логов в ряде случаев. Но конечно с выборкой описанной в статье анализ техножурнала (ИР) не сравнится по скорости.

    Reply ↓
  4. vasilev2015

    (3) Да, согласен. Поэтому позиционирую статью не как инструменты парсинга ТЖ, а как шпаргалку к экзамену. С нетерпением ждем улучшений ИР. :-))

    Reply ↓
  5. palsergeich

    (3)

    (2) Кажется обычно более разумно настроить фильтр записи журнала (logcfg.xml), чтобы он собирал то, что нужно. А не собирать в 10-100 раз больше логовов, чем нужно, неоправдано нагружая сервер и вынуждая себя пользоваться в разы менее удобными инструментами. В анализе техножурнала (ИР) непосредственно при чтении логов сейчас доступен только отбор по дате и он уже в большинстве случаев в разы ускоряет загрузку логов. Планирую туда же добавить фильтр по типу события (на этапе чтения). Он позволит еще ускорить логов в ряде случаев. Но конечно с выборкой описанной в статье анализ техножурнала (ИР) не сравнится по скорости.

    Иногда, особенно когда не знаешь почему все работает медленно, надо собрать всё, убрать главные проблемы, и после этого уже работать с ограниченным ТЖ.

    Ваш инструмент, я пользовался в том числе и им, в нем действительно удобно сводить данные, но для первичного анализа — regex, ибо в ИР к сожалению уже на 200+ тыс записях (точное число не скажу) вылетает, а клеить анализ за каждые 5 минут — не вариант.

    Очень простой пример. На прошлой неделе разбирал один ТЖ, там, помимо тех проблем о которых я догадывался, за час из сервера приложений было больше полумиллиона вызовов НайтиПоКоду в цикле в регламентном задании. С фильтром на длительность эту проблему обнаружить не удастся. НайтиПоКоду вынесен за цикл, стало сразу лучше.

    Reply ↓
  6. tormozit

    (5) Частые и одновременно легкие запросы, создающие в сумме большую нагрузку, эффективнее всего ловить через новый инструмент «Статистика запросов MSSQL», который использует не требующую включения и не создающую нагрузки статистику по запросам из процедурного кэша MSSQL. После обнаружения такого запроса в статистике MSSQL человек уже настраивает фильтр в техножурнале по тексту оператора SQL (имеется соответствующая команда в окне «Конвертор текста СУБД») и далее анализирует собранный техножурнал для выявления отправляющих этот запрос контекстов встроенного языка. Сразу через техножурнал выявлять такие запросы в разы менее непродуктивно.

    Reply ↓
  7. tormozit

    (5)

    в ИР к сожалению уже на 200+ тыс записях (точное число не скажу) вылетает

    1. Для предотвращения вылетов в 32-разрядном приложении можно использовать ограничитель по количеству загружаемых событий.

    2. Можно использовать 64-разрядное клиентское приложение, где такой проблемы, полагаю, не должно быть (не проверял тщательно).

    Reply ↓
  8. headMade

    (6) а что это за инструмент такой «Статистика запросов MSSQL». Где про него можно прочитать подробнее ?

    Reply ↓
  9. tormozit

    (8)

    Статистика

    Инструмент «Статистика по запросам MSSQL» появился в последней выпущенной версии и пока не имеет страницы с описанием. Она появится в ближайшее время. Как искать инструмент по названию, показано на картинке

    Reply ↓
  10. palsergeich

    (7)

    в ИР к сожалению уже на 200+ тыс записях (точное число не скажу) вылетает

    1. Для предотвращения вылетов в 32-разрядном приложении можно использовать ограничитель по количеству загружаемых событий.

    2. Можно использовать 64-разрядное клиентское приложение, где такой проблемы, полагаю, не должно быть (не проверял тщательно).

    1) Знаю, но даже 500 000 это мало. Пример совершенно реальной проблемы — я привел выше, можно бесконечно сидеть и делать оптимизацию в запросах дольше 0.1 секунды (чем ранее коллеги и занимались) пытаться оптимизировать, а толку будет мало.

    2) Версию клиента посмотрю, может быть и правда проблема была в версии клиента у меня и x86 и x64 стоят, спасибо за наводку.

    Reply ↓
  11. palsergeich

    (6) И за это спасибо

    Reply ↓
  12. tormozit

    (8) Добавил описание на основном сайте

    Reply ↓
  13. sanjakaiser

    Еще по этой теме есть вебинар на три часа от Виктора Богачева (экзаменатор, принимающий Эксперта). Гуглить например так: регулярные выражения Богачев

    Reply ↓
  14. starik-2005

    (0)

    Вообще, любое количество символов в регулярных выражениях означается «.*», но создателей команды cat это не смущает.

    Ну тут автор попутал маску файла и шаблон регулярного выражения. Автор, не нужно путать эти два в общем-то неодинаковых по синтаксису «языка».

    [0-9][0-9]:.{15,20}

    Ну как вариант, хотя, конечно, «d{2}:.{,20}» на мой взгляд выглядит лаконичнее и нагляднее, да и вообще я сомневаюсь, что «{15,20}» даже в обрезанном варианте здесь нужно — достаточно использовать нежадный модификатор.

    Если бы я не знал, что такое регулярные выражения, то вряд ли я с помощью данной статьи в них смог бы разобраться. Да, это очень простой и эффективный инструмент, просто необходимо разобраться в его элементах с несколькими кейсами. В этой статье кейсы есть, а теоретической части нет (да, она, конечно, выходит за рамки статьи, но т.к. занимает мало, то могли бы и включить).

    По-сути, регулярные выражения очень хорошо позволяют извлекать текст из текста и модифицировать текст, что зачастую даже важнее поиска (по поводу простого сравнения с шаблоном по регулярке, то в 1С есть механизм XDTO, который может с этим справиться на любой поддерживаемой ОС без внешних компонент). А вот менять он не умеет. При том простой кейс замены даты, выгруженной в обычном формате 1С (ДД-ММ-ГГГГ чч:мм) можно поменять на XML-формат (YYYY-MM-DD) с помощью групп вот таким образом:

    Шаблон поиска:

    >(dd).(dd).(d{4})( dd:dd)<

    Шаблон замены:

    >3-2-1<

    Т.е. определяются группы (то. что в скобках). Дальше эти группы по номеру используются в шаблоне замены, в итоге сначала выводится 3-я группа с годом, потом вторая, потом первая. Таких шаблончиков разобрать штук десять — и все, регулярки освоены. Дальше можно делать с ними все на свете.

    Reply ↓
  15. kudlach

    Извиняюсь, но термин «регулярные выражения» — это немного не к журналу регистрации изначально. Это к стыку мат.анализа , теории множеств и азам программирования.

    Отдельная тема к экзаменам второго курса ВУЗа.

    Думается мне, более правильно тема звучала бы «Применение регулярных выражений в решении задач таких-то«

    Reply ↓
  16. vasilev2015

    (15) Про регулярные выражения лучше прочитать в книге Джеффри Фридла «Регулярные выражения». В статье — приложение на практике, приближенное к экзамену.

    Reply ↓
  17. starik-2005

    (17)

    Про регулярные выражения лучше прочитать в книге

    Вы читали в книге? Как оно там? Сколько страничек? Если читали, то зачем пишите «[0-9]» вместо «d»?

    На мой взгляд, сначала лучше в ВИКИ читнуть, поиграться с notepad++, потом с grep (кстати, никогда не юзал egrep — чем он отличается?), потом с sed. В итоге за пару дней освоится основной функционал, которого уже будет для большинства задач за глаза. А дальше, если хочется стать экспертом не только в 1С, а еще и в регулярных выражениях, можно перейти к книгам (но я бы, лично, из книг порекомендовал «Бытие и Время«, а то все хотят стать экспертами, а зачем — не знают )))

    Reply ↓
  18. vasilev2015

    (18) да, читал. Использую [0-9] вместо «d» поскольку [0-9] работает там, где иногда не работает «d». Egrep равносилен grep с ключом -e. Экспертом хочу стать по-приколу: могу себе позволить.

    Reply ↓
  19. starik-2005

    (19) в вики написано, что это одно и то же, только синтаксис регулярок упрощен, а для полного нужно заэкранировать спецсимволы.

    Интересно стало, где «[0-9]» работает, а «d» — нет… Сходу не смог ничего такого придумать. Подскажете?

    Reply ↓
  20. leemuar

    (20) Насколько я помню d не является метасимволом в posix, только в pcre. Шанс нарваться сегодня на утилиту, не умеющую pcre довольно мал.

    За написание [0-9] вместо d есть большой аргумент: удобочитаемость. Регулярки очень сложно читать. Помнить и расшифровывать все метасимволы достаточно неудобно. Использование простого диапазона повышает «понимаемость» регулярки.

    А так, конечно, разницы в получаемом результате нет

    Reply ↓
  21. mvxyz

    (16) Нормальное название статьи. Тем кто готовится к экзамену на эксперта сразу понятно о чем речь. Автору спасибо.

    Reply ↓
  22. starik-2005

    (22)

    За написание [0-9] вместо d есть большой аргумент: удобочитаемость. Регулярки очень сложно читать. Помнить и расшифровывать все метасимволы достаточно неудобно. Использование простого диапазона повышает «понимаемость» регулярки.

    А мне, лично, кажется, что короче — в данном конкретном случае лучше. Я тут видел в XBRL ЦБ таких регулярок в шаблоны наклал, что страшно становится. Например, они написали полное выражения для корректного диапазона дат (при том для текстового элемента открытой оси). И вот этот огород в двести символов (а может и больше) определенным образом напрягает. Они там все феврали вырисовали с учетом високосных лет, например. И все это мельтешит через «|» и цифры.

    Reply ↓
  23. sanjakaiser

    К сожалению, отредактировать предыдущий мой пост уже нельзя, вот видео Богачева

    https://www.youtube.com/watch?v=pV8wgI8haf4.

    (Не реклама) Автор дает представление о том, что такое регулярки, почему их надо использовать при анализе ТЖ, ну и на практике показывает, куда это запрягать + Это тот человек, который принимает у вас экзамен 1С:Эксперт

    Reply ↓
  24. vasilev2015

    (24) спасибо, полезная информация.

    Reply ↓
  25. Dach

    (12) Извините за оффтоп, но раз уж тут пошла речь…

    Если в конфигурацию не встроена обработка ирАнализТехноЖурнала — отчет сбора статистики не запускается.

    Имею ввиду из портативной версии ИР.

    Пришлось найти все вхождения и закомментить:

    ПриКомпоновкеРезультата(

    ……

    АнализТехножурнала = Обработки.ирАнализТехножурнала.Создать();

    Reply ↓
  26. Dach

    Пользуясь случаем (простите за оффтоп еще раз), раз в ветке отметились мастера разбора ТЖ, хочу посоветоваться…

    Есть большая БД, РИБ. Я верно понимаю, что если настраивать ТЖ, то это придется делать во всех узлах и потом выполнять некий сводный анализ? Втом числе, наверное и с помощью регулярок.

    И еще момент… Мы встроили в конфу БСП и подсистему «Оценка производительности». Планируем выявить самые «нехорошие места» сначала ей, а потом, как мне кажется — можно уже и ТЖ более детально настроить… Может кто-то пользовался подсистемой? Поделитесь впечатлениями, плз.

    Reply ↓
  27. vasilev2015

    (27) я не очень мастер, но поскольку ветка моя — постараюсь ответить. Если у вас есть планы парсить, проводить анализ и искать узкие места в дочерних базах, то настраивайте там ТЖ. Если нет планов — «впрок» не делайте. Обязательно следите за местом, которое потребляет ТЖ.

    Оценка производительности незаменима для общения с заказчиком: у вас апдекс был 0,6 а теперь 0,85 — извольте заплатить. Для себя апдекс тоже интересен: смотреть, что операторы проводят заказы по 59 секунд и удивляться их терпению. Или постфактум обосновать полезность приобретения нового raid. Менеджеры привыкли верить цифрам и красивым графикам.

    Reply ↓
  28. tormozit

    (26) Было бы классно увидеть багрепорт там, где все ожидают его увидеть и подробно оформленный. Проблему воспроизвел.

    Reply ↓
  29. lustin

    я конечно понимаю что регулярные выражения это просто — но точно не для 1С-ников. А вот ниже регулярки уже для них.

    #Использовать verbal-expressions
    
    // Проверим корректность формирования URL. Допустимые схемы — http[s] и ftp
    
    ЭкранироватьПереданноеЗначение = Ложь;
    
    ВербальноеВыражение = Новый ВербальноеВыражение()
    .НачалоСтроки()
    .Затем(
    Новый ВербальноеВыражение()
    .Найти(«http»)
    .МожетБыть(«s»)
    .Либо(«ftp»)
    .ВСтроку(),
    ЭкранироватьПереданноеЗначение
    )
    .Затем(«://»)
    .ЧтоНибудьНоНе(» «)
    .КонецСтроки();
    
    ТекстРегулярногоВыражения = ВербальноеВыражение.ВСтроку();
    Сообщить(ТекстРегулярногоВыражения);
    
    

    Показать

    P.S. а вы никогда не задумывались над тем почему вместо изучения регулярок и сдачи их на экзамене просто не поменять формат журнала технологического. Сюрррреализм.

    Reply ↓
  30. starik-2005

    (30)

    P.S. а вы никогда не задумывались над тем почему вместо изучения регулярок и сдачи их на экзамене просто не поменять формат журнала технологического. Сюрррреализм.

    А какой формат ТЖ поможет сделать его анализ без поиска текста? Даже интересно стало…

    Reply ↓

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *