¿Cómo puedo encontrar el formato para un subconjunto de texto en una celda de documento de Excel?

Usando Python, necesito encontrar todas las subcadenas en una celda de hoja de Excel dada que estén en negrita o en cursiva.

Mi problema es similar a este:

Usando el módulo XLRD y Python para determinar el estilo de fuente de celda (en cursiva o no)

..pero la solución no es aplicable para mí ya que no puedo asumir que el mismo formato es válido para todo el contenido de la celda. El valor en una sola celda puede verse así:


1. Algunos texto en negrita Algunos texto normal. Algunos texto en cursiva .


¿Hay alguna forma de encontrar el formato de un rango de caracteres en una celda usando xlrd (o cualquier otro módulo de Python Excel)?

Gracias a @Vyassa por todos los punteros correctos, he podido escribir el siguiente código que recorre las filas en un archivo XLS y genera información de estilo para celdas con información de estilo “única” (por ejemplo, toda la celda es cursiva ) o estilo “segmentos” (por ejemplo, parte de la celda es cursiva, parte de ella no lo es).

import xlrd # accessing Column 'C' in this example COL_IDX = 2 book = xlrd.open_workbook('your-file.xls', formatting_info=True) first_sheet = book.sheet_by_index(0) for row_idx in range(first_sheet.nrows): text_cell = first_sheet.cell_value(row_idx, COL_IDX) text_cell_xf = book.xf_list[first_sheet.cell_xf_index(row_idx, COL_IDX)] # skip rows where cell is empty if not text_cell: continue print text_cell, text_cell_runlist = first_sheet.rich_text_runlist_map.get((row_idx, COL_IDX)) if text_cell_runlist: print '(cell multi style) SEGMENTS:' segments = [] for segment_idx in range(len(text_cell_runlist)): start = text_cell_runlist[segment_idx][0] # the last segment starts at given 'start' and ends at the end of the string end = None if segment_idx != len(text_cell_runlist) - 1: end = text_cell_runlist[segment_idx + 1][0] segment_text = text_cell[start:end] segments.append({ 'text': segment_text, 'font': book.font_list[text_cell_runlist[segment_idx][1]] }) # segments did not start at beginning, assume cell starts with text styled as the cell if text_cell_runlist[0][0] != 0: segments.insert(0, { 'text': text_cell[:text_cell_runlist[0][0]], 'font': book.font_list[text_cell_xf.font_index] }) for segment in segments: print segment['text'], print 'italic:', segment['font'].italic, print 'bold:', segment['font'].bold else: print '(cell single style)', print 'italic:', book.font_list[text_cell_xf.font_index].italic, print 'bold:', book.font_list[text_cell_xf.font_index].bold 

xlrd puede hacer esto. Debe llamar a load_workbook() con kwarg formatting_info=True , luego los objetos de hoja tendrán un atributo rich_text_runlist_map que es un diccionario que asigna coordenadas de celda ( (row, col) tuplas) a una lista de ejecución para esa celda. Una lista de ejecución es una secuencia de (offset, font_index) pares donde offset le indica en qué punto de la celda comienza la fuente, y los índices de font_index en el atributo font_list del objeto del libro de font_list (el objeto de libro es lo que devuelve load_workbook() ), que le da Objeto de fuente que describe las propiedades de la fuente, como negrita, cursiva, tipo de letra, tamaño, etc.

No sé si puedes hacer eso con xlrd , pero como preguntas sobre cualquier otro módulo de Python Excel: openpyxl no puede hacer esto en la versión 1.6.1.

El texto enriquecido se reconstruye en la función get_string() en openpyxl/reader/strings.py . Sería relativamente fácil configurar una segunda tabla con cadenas “sin procesar” en ese módulo.