【问题标题】:Matching Regex in Python from Excelfile从 Excelfile 匹配 Python 中的正则表达式
【发布时间】:2020-08-30 22:13:04
【问题描述】:

我正在使用正则表达式来匹配以下 excel 文件,我正在努力解决我的问题 用

分隔每一行

时间戳[0:00:48], 编号20052A 和内容content (more content)

这是 excel 行(许多行之一,因此 ID 可能因行和时间戳以及内容而异)

[0:00:48] 20052A: content (more content)

我收到错误代码

AttributeError: 'NoneType' object has no attribute 'group

用于匹配我的身份证件

(r"^(.+:)(.+)|(r(\w+)?\s*\[(.*)\]\s*(\w+))", c)

请记住,ID 有时看起来像这样

[0:00:33] 30091aA: (content) 

我的整个脚本是(取消与数据库的连接)

import os
import re
import pymysql
pymysql.install_as_MySQLdb()
import pandas as pd
import sqlalchemy


def insert_or_update(engine, pd_table, table_name):
    inserts = 0
    updates = 0
    for i in range(len(pd_table)):
        vals_with_quotes = ["'" + str(x) + "'" for x in pd_table.loc[i, :].values]
        # print(vals_with_quotes)
        update_pairs = [str(c) + " = '" + str(v) + "'" for c, v in zip(pd_table.columns, pd_table.loc[i, :])]
        query = f"INSERT INTO {table_name} ({', '.join(list(pd_table.columns.values))}) " \
                f"VALUES ({', '.join(vals_with_quotes)}) " \
                f"ON DUPLICATE KEY UPDATE {', '.join(update_pairs)}"
        print(query)
        result = engine.execute(query)
        if result.lastrowid == 0:
            updates += 1
        else:
            inserts += 1
    print(f"Inserted {inserts} rows and updated {updates} rows.")


schema = '---'
alchemy_connect = "---"
engine = sqlalchemy.create_engine(alchemy_connect)  # connect to server
engine.execute(f"USE {schema}")  # select new db
# engine.execute("SET NAMES UTF8MB4;")

query = "SELECT * FROM .... where ...=..."
pm = pd.read_sql(query, engine)

rootpath = "path/"

for root, dirs, files in os.walk(rootpath):
    for file in files:
        print(root, dirs, files, file)
        d = pd.read_excel(root + file, header=None)
        d.drop(columns=[0], inplace=True)
        d.rename(columns={1: "content"}, inplace=True)

        participants = []

        for ix, row in d.iterrows():
            c = row["content"]

            match = re.search(r"^(.+:)(.+)|(r(\w+)?\s*\[(.*)\]\s*(\w+))", c)
            prefix = match.group(1)
            only_content = match.group(2)

            try:
                timestamp = re.search(r"\[(\d{1,2}:\d{1,2}:\d{1,2})\]", prefix).group(1)
            except:
                timestamp = "-99"
            # print(timestamp)

            if re.search(r"\s(Versuchsleiter|ersuchsleiter|Versuchsleit|Versuch):", prefix):
                id_code = "Versuchsleiter"
            else:
                starting_digits = re.search(r"^(\d+)", prefix)
                id_code = re.search(r"(\d{2,4}.{1,3}):", prefix).group(1)
                if hasattr(starting_digits, 'group'):
                    id_code = starting_digits.group(1) + id_code  #

            # get pid
            participant = pm.loc[pm["id_code"] == id_code, "pid"]
            try:
                pid = participant.values[0]
            except:
                pid = "Versuchsleiter"

            # print(ix, pid, id_code, only_content, timestamp)
            if pid and pid not in participants and pid != "Versuchsleiter":
                participants.append(pid)
            d.loc[ix, "pid"] = pid
            d.loc[ix, "timestamp"] = timestamp
            d.loc[ix, "content"] = only_content.strip()
            d.loc[ix, "is_participant"] = 0 if pid == "Versuchsleiter" else 1

        d = d[["pid", "is_participant", "content", "timestamp"]]
        d.loc[(d['pid'] == "Versuchsleiter"), "pid"] = participants[0]
        d.loc[(d['pid'] == None), "pid"] = participants[0]
        insert_or_update(engine, d, "table of sql")```


I need "Versuchsleiter" since some of the ID's are "Versuchsleiter"

Thank you!

【问题讨论】:

  • 试试^\[(?P<timestamp>[^][]*)]\s*(?P<ID>\w+):\s*(?P<content>.*),见demo
  • 我只是想匹配ID部分,ID可以逐行变化,所以不能只复制ID码
  • 试试(?<=:\d{2}]\s)\w+(?=:),见demo。你的代码是什么?请分享。使用^\[[^][]*)]\s*(\w+): 并获得第 1 组可能没问题
  • 查看我的新编辑 :)
  • 看,您可以使用单个正则表达式获取所有详细信息 - ^\[(\d+:\d+:\d+)]\s+(\d*)(\w+):\s+(.+) (demo)。

标签: python python-3.x regex excel


【解决方案1】:

感谢您的帮助,但这给了我以下错误

Traceback (most recent call last):
  File "C:/Users/.../PycharmProjects/.../.../....py", line 80, in <module>
    insert_or_update(engine, d, "sql table")

TypeError: not enough arguments for format string

【讨论】:

    【解决方案2】:

    您应该利用capturing groups

    所有初始正则表达式匹配(c = row["content"] 之后和# get pid 之前)都可以用

    完成
    match = re.search(r"^\[(\d{1,2}:\d{1,2}:\d{1,2})]\s+(\w+):\s*(.*)", c)
    if match:
      timestamp = match.group(1)
      id_code = match.group(2)
      only_content = match.group(3)
      if re.search(r"(?:Versuch(?:sleit(?:er)?)?|ersuchsleiter)", id_code):
        id_code = "Versuchsleiter"
    

    您的时间戳将为0:00:33,only_content 将包含(content),id_code 将包含30091aA

    regex demo

    【讨论】:

    • 感谢您的帮助,但这给了我以下错误
    • @Shuzo 我不知道您是如何在您的代码中使用我的代码的,但是当您看到我的代码有效时,您在某处有错字。它还展示了如何提取 ID。
    • 我收到了几个错误代码,例如(TypeError: not enough arguments for format string)或(第 590 行,在 do_execute cursor.execute(statement, parameters))
    猜你喜欢
    • 2016-07-01
    • 2013-09-22
    • 1970-01-01
    • 1970-01-01
    • 2022-12-11
    • 2015-09-14
    • 2021-12-31
    • 2018-12-30
    • 1970-01-01
    相关资源
    最近更新 更多