Регулярные выражения для Python c использование openpyxl

введите сюда описание изображения

Написал скрипт для сбора логов СХД NetApp:

import openpyxl
import subprocess
import os
import datetime
import re

time = datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S')
path_to_SMCIPMItool = 'C:/Program Files/StorageManager/client/SMcli.exe'
wb = openpyxl.reader.excel.load_workbook(filename='D:/PythonScritps/NetApp-SN.xlsx')
ws = wb.active

def log_collector():
    while True:
        sanName = input('Enter the name of storage system in 07-06 format: ')
        for row in ws.rows:
            for cell in row:
                if cell.value == sanName:
                    storage_name = str(ws.cell(row=cell.row, column=1).value)
                    storage_rack = ws.cell(row=cell.row, column=2).value
                    storage_sn_depo = ws.cell(row=cell.row, column=3).value
                    storage_sn_manufactur = ws.cell(row=cell.row, column=4).value
                    storage_unit = ws.cell(row=cell.row, column=5).value
                    print('Serial number of ' + storage_name + ' is ' + storage_sn_depo + ' and serial number of Netapp ' + storage_sn_manufactur)
                    print(storage_name + ' is installed in the rack ' + storage_rack + ' and unite ' + storage_unit)
                    return storage_name

        else:
            cell.value != sanName
            print('not found this storage, try again')

В функции идёт обращение к Excel файлу, который имеет в первой колонке имена СХД (например ST13-06-b) и вторая колонка (например 13-06). Когда пользователь через input вводит 13-06, через 2 цикла for проходится по Excel файлу, и если выполняется условие if cell.vallue == sanName (вторая колонка Excel файла (cell.vallue) == 13-06(input) вытаскивает нужные значения из каждой ячейки. Мне пришлось вводить эту доп колонку с такими названиями(13-06 и т.д), но это немного читерство. Я бы хотел использовать регулярные выражение для поиска, вводя 13-06, а находил значение в ячейке ST13-06-b.

И вот что получается на выходе скрипта:

Enter the name of storage system in 07-06 format: 13-06
Serial number of ST13-06-b is xxxxxx and serial number of Netapp xxxxxxx
ST13-06-b is installed in the rack Стойка xxxxx and unite xxxxx

Приведу ниже пример отдельного кода как я пытался играться с регулярными выражениям и вот что получилось.

import re
txt = 'ST13-03-b'

look = r"[\w-]+"

all = re.findall(look,txt)
print(all)

Подойдёт ли это составленное регулярное выражение и можно ли его использовать при поиске ячеек в Excel и как правильно это сделать?


Ответы (1 шт):

Автор решения: MaxU

Воспользуйтесь модулем Pandas.

Рабочий пример (используем Single-responsibility Principle):

import re
import pandas as pd
from pathlib import Path
from typing import Union, Dict

def parse_log_to_df(filename: Union[str, Path], **kwargs) -> pd.DataFrame:
    return pd.read_excel(filename, **kwargs)

def find_log_entry(
        df: pd.DataFrame,
        san_regex: Union[str, re.Pattern],
        search_col: str = "Name"
) -> Dict[str, str]:
    res = df.loc[df[search_col].str.contains(san_regex)]
    if res.empty:
        return None
    res = res.iloc[0].to_dict()
    return res

def build_report(df: pd.DataFrame, san_regex: Union[str, re.Pattern]) -> str:
    r = find_log_entry(df, san_regex)
    if not r:
         return None
    res = (f'Serial number of {r.get("Name")} is {r.get("SN_DEPO")} '
           f'and serial number of Netapp {r.get("manufactur")}\n'
           f'{r.get("Name")} is installed in the rack {r.get("Rack")}'
           f' and unit {r.get("Unit")}')
    return res
    

df = parse_log_to_df(filename)
san_regex = "06-03"
print(build_report(df, san_regex))
# Serial number of ST06-03-b is xxxxx and serial number of Netapp xxxxx
# ST06-03-b is installed in the rack xxxxx and unit xxxxx

print(build_report(df, san_regex=r"01.*-g$"))
# Serial number of ST01-03-g is xxxxx and serial number of Netapp xxxxx
# ST01-03-g is installed in the rack xxxxx and unit xxxxx
→ Ссылка