суббота, 15 июля 2017 г.

Автоматизация в блокноте. Изменился порядок записей в тесте, меняем регэкспами

Мы решили поменять плоскую запись ФИО на нормализованную. Это чтобы учесть всякие изменения типа Киселева Ольга → Назина Ольга. Теперь мне надо поднять тесты. Ведь на входе теперь вместо одной строки будет две:


;1-01;КЛИМОВА;НАДЕЖДА;ЛЬВОВНА;27.04.1976;;;;BANK



;1-01;27.04.1976;;;;BANK
fio;;КЛИМОВА;НАДЕЖДА;ЛЬВОВНА;EDITED


Тесты написаны в csv файле, их можно открыть через блокнот. В тесте 300 строк, из них треть занимают строки с ФИО. Как менять будем, вручную? Безудержное веселье

Менять 100 строк ручками? Ок
Конечно, нет.
Нужно написать регэксп, а блокнот потом все сделает за нас.

Блокнот не даст заменить одну строку на две. Хм, тогда можно склеить ожидаемый результат с помощью символа, которого точно нет в файлике, а потом разделить строки по нему. Получается переход в два этапа:

;1-01;КЛИМОВА;НАДЕЖДА;ЛЬВОВНА;27.04.1976;;;;BANK



;1-01;27.04.1976;;;;BANK&fio;;КЛИМОВА;НАДЕЖДА;ЛЬВОВНА;EDITED



;1-01;27.04.1976;;;;BANK
fio;;КЛИМОВА;НАДЕЖДА;ЛЬВОВНА;EDITED


Возьмем эту строчку и перенесем на другую вкладку блокнота — для отладки. Сначала проверим на ней, а потом уже будем применять шаги ко всему файлу.


1. Регэскпы


Чтобы понять, какая колонка в какую уедет, посмотрим в репозитории изменения. Что в какой колонке лежало и в какую переехало.


Ну, ФИО переедет на вторую строку, тут все понятно.
Дата рождения 27.04.1976 — ага, была в ячейке номер 5, а стала в ячейке номер 2. А ИНН из 6 ячейки переехал в 3. В общем, сдвиг понятен. Запишем в виде регэкспа:

;(\d*-\d*);(.*);(.*);(.*);(\d{2}.\d{2}\.\d{4});(.*);(.*);(.*);(.*)



;\1;\5;\6;\7;\8;\9&fio;;\2;\3;\4;EDITED

В Notepad++ открываем Ctrl + F (поиск) → вкладка «Заменить». Заменяем по регулярному выражению.

Этап 1. Обрабатываем строку регэкспами

2. Перенос на новую строку


Теперь делаем замену по расширенному режиму:

& → \r\n

Этап 2. Разделяем одну строку на две

Вставим ниже эталонный результат, составленный перед всеми этими манипуляциями вручную. 

Сравнили с эталоном — совпадает!

Ю-ху, они идентичны! Работает?

3. Тестирование и отладка


Конечно, когда в файлике 1 строка, все будет работать. А когда 300?

Первый прогон подменил только 40 строк. Смотрим почему. Ага, нумерация в файлике пока не везде через тире. Меняем (\d*-\d*) → (.*). Еще 20 строк. Смотрим что в оставшихся. Ах да, дата рождения есть не всегда. Ха, так ведь сразу можно было написать более универсальный регэксп:

;(.*);(.*);(.*);(.*);(.*);(.*);(.*);(.*);(.*)


;\1;\5;\6;\7;\8;\9&fio;;\2;\3;\4;EDITED

Ура, еще 60 строк обработано! Мотаем тест, проверяя глазками — вроде все норм, ФИО разнесено на две строки. Запускаем тест... Сработает?

Если вы когда-то работали с регэкспами, то вы наверняка увидели мою ошибку Smile :)
Тест упал. Потому что в нем не только строки с ФИО. Есть и более длинные, которые я своим регэкспом разбила на две со словом fio во второй.

Никогда не забываем про символы начала и окончания строки! Мне пришлось полностью откатить изменения в файле и потом повторить манипуляции с нуля. Итого получили «правильные» два этапа, меняем только строки, в которых 9 ячеек — это строки с ФИО:


^;(.*);(.*);(.*);(.*);(.*);(.*);(.*);(.*);(.*)$



;\1;\5;\6;\7;\8;\9&fio;;\2;\3;\4;EDITED


& → \r\n

100 строк изменено. Тест прошел! Ура Big grin :D

Вот так все просто. Конечно, будь в файлике 10 строк, проще было бы заменить вручную. Хотя... Тоже сомнительно, человеческий фактор и вот это вот все. Делая рутину, ляпаешь ошибки. Когда нужно что-то массово заменить, лучше использовать автоматизацию. 

Да, автоматизация — это не только знание кода. Это может быть и такая простая манипуляция с обычным блокнотом. Которая при этом превращает унылую задачу в интересненькую Wink ;)

2 комментария:

  1. Ответы
    1. Это простые регэкспы :-)
      Базовые знания, так сказать ))))

      Сделаю что-нить потом по регэкспам, статей или видео

      Удалить