在 Python 中解析多管道分隔表

问题描述 投票:0回答:1

我想创建一个函数,使用这个字符串来创建一个表格,即使有中断,它也能正常工作,如下例所示

当一条数据被成对的管道包围时,它是一列,当它只被2个管道包围时,它是每列的值

||Name||Age||Address||Phones||size||  
|Edwards|22|London|06 45 06 06 06  
06 75 85 06 06  
07 85 22 15 48|180cm|

(我输入

\n
因为我无法返回到此表中的行,但它们应该位于同一个单元格中)

| Names | Age | Address | Phones | Size |
| --- | --- | --- | --- | --- |
| Edwards | 22 | London | 06 45 06 06 \\n06 06 75 85 06 06\\n 07 85 22 15 48 | 180cm |

这是我创建的函数之一,但当值出现中断时它不起作用;

def traiter_colonne_description(df):
    
    dictionnaire_donnees = {}
    for index, row in df.iterrows():
        texte_modifie = row['Description'].replace('*', '')  # Enlever toutes les étoiles
        colonnes = []
        texte_description = ""
        
        lignes = texte_modifie.strip().split('\n')
        dans_section_description = False
        compteur_lignes = 0
        
        for ligne in lignes:
            ligne = ligne.strip()
            dans_section_description, compteur_lignes, texte_description = traiter_ligne_description(
                ligne, dans_section_description, compteur_lignes, texte_description )
            
            if '||' in ligne:
                noms_colonnes = re.split(r'\|\|', ligne)
                colonnes = [col.strip() for col in noms_colonnes if col.strip()]
                for col in colonnes:
                    if col not in dictionnaire_donnees:
                        dictionnaire_donnees[col] = []
            
            elif '|' in ligne and colonnes:
                # Si une ligne contient |, on traite les valeurs
                ligne_sans_barre = ligne.replace('|', '').strip()  # Enlever le caractère |
                
                # Vérifier si la ligne contient un retour à la ligne
                if '\n' in ligne_sans_barre:
                    # Si c'est le cas, on ne concatène pas, on ajoute une nouvelle entrée
                    valeurs = re.split(r'\|', ligne)
                    valeurs = [valeur.strip() for valeur in valeurs if valeur.strip()]
                    
                    # Assurer que le nombre de colonnes et de valeurs correspond
                    while len(valeurs) < len(colonnes):
                        valeurs.append('')
                    for col, valeur in zip(colonnes, valeurs):
                        dictionnaire_donnees[col].append(valeur)
                else:
                    # Si la ligne ne contient pas de retour à la ligne, on concatène
                    if dictionnaire_donnees[colonnes[-1]]:
                        # Concaténer uniquement si la dernière valeur existe
                        dictionnaire_donnees[colonnes[-1]][-1] += ' ' + ligne_sans_barre
                    else:
                        # Sinon, on traite normalement comme une nouvelle valeur
                        valeurs = re.split(r'\|', ligne)
                        valeurs = [valeur.strip() for valeur in valeurs if valeur.strip()]
                        
                        if len(colonnes) == len(valeurs):
                            for col, valeur in zip(colonnes, valeurs):
                                dictionnaire_donnees[col].append(valeur)
                        else:
                            # Si le nombre de colonnes et de valeurs ne correspond pas, ajouter des valeurs vides
                            while len(valeurs) < len(colonnes):
                                valeurs.append('')
                            for col, valeur in zip(colonnes, valeurs):
                                dictionnaire_donnees[col].append(valeur)
        
        dictionnaire_donnees['Description'] = [texte_description.strip()]
    return dictionnaire_donnees
python python-3.x pandas dataframe openpyxl
1个回答
0
投票

你可以尝试:

import re
import csv
from io import StringIO

import pandas as pd

data = """\
||Name||Age||Address||Phones||size||  
|Edwards|22|London|06 45 06 06 06  
06 75 85 06 06  
07 85 22 15 48|180cm|"""

data = re.sub(r"(?!<\|)\|\|", "|", data)         # <-- convert || to single |
data = re.sub(r"^\s*\|", '"', data, flags=re.M)  # <-- convert beginning | to "
data = re.sub(r"\|\s*$", '"', data, flags=re.M)  # <-- convert ending | to "
data = re.sub(r"\|", '"|"', data)                # <-- convert | to "|"

# the data is transformed to:

# "Name"|"Age"|"Address"|"Phones"|"size"
# "Edwards"|"22"|"London"|"06 45 06 06 06  
# 06 75 85 06 06  
# 07 85 22 15 48"|"180cm"

r = csv.reader(StringIO(data), quotechar='"', delimiter="|")
df = pd.DataFrame(r, columns=next(r))

print(df)

打印:

姓名 年龄 地址 电话 尺寸
爱德华兹 22 伦敦 06 45 06 06 06 180厘米
06 75 85 06 06
07 85 22 15 48
© www.soinside.com 2019 - 2024. All rights reserved.