Python – 从电子邮件中提取信息

我是Python的新手。以下是我收到的样本电子邮件。

电子邮件样本1

亲爱的各位,

请注意总销售量和总剩余库存

总销售量:45677总剩余库存A:3456

如有任何疑问或评论,请随时联系我。

此致,

电子邮件样本2

亲爱的各位,

请查看以下数据:

总量:1,231,245剩余库存A数量:232剩余库存B数量:1,435

电子邮件样本3

亲爱的各位,

请查看我们的量为233,435

总剩余库存A:2453

电子邮件样本4

五月我们有90个剩余库存A和4190个TEU。

我想从这些电子邮件中提取量和总剩余库存数据。如果我可以使用Python来获取这些数据,有什么提示吗?

我已经准备了下面的代码来从电子邮件中提取数据。但是我无法区分哪个数据是总销售量,哪个是总剩余库存

import reimport pandas as pdimport win32com.clientfrom datetime import datetime, timedeltaoutlook = win32com.client.Dispatch('outlook.application')mapi = outlook.GetNamespace("MAPI")inbox = mapi.GetDefaultFolder(6).Folders.Item("AI email testing")#outlook.GetDefaultFolder(6) .Folders.Item("Your_Folder_Name")#inbox = outlook.GetDefaultFolder(6)messages = inbox.Itemsreceived_dt = datetime.now() - timedelta(days=1)received_dt = received_dt.strftime('%m/%d/%Y %H:%M %p')for message in list(messages):    #print (message)    body_content = message.body    body_content =body_content[body_content.find("Subject:"):]    #print(body_content)    figures = re.findall("\d+(?:,\d+)*(?:\.\d+)?",body_content)    print(figures)

回答:

这里有一个使用正则表达式的解决方案:

from __future__ import annotationsimport refrom typing import List, Tupledef get_number(text: str) -> float | int | str:    """    从输入字符串中提取第一个数值。    该函数使用正则表达式从`text`中提取第一个数值出现。如果没有找到数值,则返回原始字符串。    从提取的数字中删除逗号(如果有)。    该函数首先尝试将数字转换为整数,如果失败,则尝试转换为浮点数。    参数    ----------    text : str        应从中提取数值的字符串。    返回    -------    float | int | str        `text`中的第一个数值转换为int或float,        或者如果没有找到数值,则返回原始`text`。    引发    ------    ValueError        如果提取的数字无法转换为整数或浮点数。    示例    --------    函数使用和行为的说明。    >>> get_number("Hello world 123!")    123    >>> get_number("I have 2,200 dollars.")    2200    >>> get_number("No numbers here.")    'No numbers here.'    >>> get_number("It is over 9000!")    9000    >>> get_number("The value of pi is about 3.14159.")    3.14159    >>> get_number("Total: 123,456,789.")    123456789.0    """    number = re.search(r'(\d+|,)+.', text, re.I)    if number:        number = number[0].strip().replace(',', '')    if not number:        print(f"Found no numbers inside text: {text!r}")        return text    try:        return int(number)    except ValueError:        return float(number)def extract_stock_volume_from_email(email: str) -> Tuple[int | float | str, int | float | str]:    """    从电子邮件文本中提取量和剩余库存A的详细信息。    此函数使用正则表达式解析给定的电子邮件文本并    提取关于量和剩余库存A的详细信息。    提取的值随后被清理并返回。    参数    ----------    email : str        要解析的电子邮件文本。    返回    -------    volume : int | float | str        从电子邮件中提取的量。        如果没有找到量详细信息,则返回'Volume not found'。    remaining_stock_a : int | float | str        从电子邮件中提取的剩余库存A。        如果没有找到库存A详细信息,则返回'Remaining stock A not found'。    引发    ------    re.error        如果使用了无效的正则表达式。    另见    --------    re.search : 用于提取量和剩余库存详细信息的方法。    示例    --------    >>> email_text = "The volume was 5000 TEUs. Stock A: 1000 units."    >>> extract_stock_volume_from_email(email_text)    (5000, 1000)    >>> email_text = "No volume and stock data available."    >>> extract_stock_volume_from_email(email_text)    ('Volume not found', 'Remaining stock A not found')    """    # 提取量    volume = re.search(        r'(?:volume:|volume was|TEUs\.|TEUs |TEU |$)\s(\d+|,)+.*?|(\d+|,)+.(?:\sTEUs|\sTEU)',        email, re.I    )    if volume:        volume = get_number(volume[0].strip())    if not volume:        volume = 'Volume not found'    # 提取剩余库存    remaining_stock_a = re.search(r'(?:stock A:|stock A: |$)(\d+|,)+.*?', email, re.I)    if remaining_stock_a:        remaining_stock_a = remaining_stock_a[0].strip()    if not remaining_stock_a:        remaining_stock_a = re.search(r'(\d+)(.+)(stock A)', email, re.I)        if remaining_stock_a:            remaining_stock_a = remaining_stock_a[0].strip()    if remaining_stock_a:        remaining_stock_a = get_number(remaining_stock_a)    if not remaining_stock_a:        remaining_stock_a = 'Remaining stock A not found'    # print(f"Volume: {volume}\nRemaining Stock A: {remaining_stock_a}\n")    return volume, remaining_stock_adef extract_stock_volume_from_emails(    emails: List[str],) -> List[Tuple[int | float | str, int | float | str]]:    """    将函数`extract_stock_volume_from_email`应用于电子邮件列表。    参数    ----------    emails : List[str]        要解析的电子邮件文本列表。    返回    -------    List[Tuple[int | float | str, int | float | str]]        一个元组列表。每个元组包含从每个电子邮件中提取的量和剩余库存A。        如果无法从电子邮件中提取量或库存A详细信息,则元组中相应的元素将是        'Volume not found'或'Remaining stock A not found'。    引发    ------    re.error        如果在`extract_stock_volume_from_email`中使用了无效的正则表达式。    另见    --------    extract_stock_volume_from_email : 用于从每个电子邮件中提取详细信息的函数。    示例    --------    >>> email_texts = [    ...     "The volume was 5000 TEUs. Stock A: 1000 units.",    ...     "No volume and stock data available.",    ... ]    >>> extract_stock_volume_from_emails(email_texts)    [(5000, 1000), ('Volume not found', 'Remaining stock A not found')]    """    return list(map(extract_stock_volume_from_email, emails))

使用上述代码处理您提供的示例电子邮件:

emails = [    r"""Dear all,Please note the Total selling volume and total remaining stockTotal selling volume: 45677 Total remaining stock A:3456Remain at your disposal in case of any doubt or comments.Best Regards,""",    r"""Dear all,Please see the data as below:Tol volume: 1,231,245 No. of remaining stock A: 232 No. of remaining stock B: 1,435""",    r"""Dear All,Please find our volume was 233,435Total remaining stock A: 2453""",    r"In May we had 90 remaining stock A and 4190 TEUs.",]extract_stock_volume_from_emails(emails)# Returns:## [(45677, 3456), (1231245, 232), (233435, 2453), (4190, 90)]#  ^----^  ^--^#  |       |#  |       +-- Remaining stock A#  +-- Volume

注意

需要注意的是,解析每个电子邮件的函数extract_stock_volume_from_email并非万无一失。其中包含的正则表达式模式都是基于您提供的示例电子邮件。如果其他电子邮件不遵循与示例电子邮件相同的模式,则需要将这些额外的模式添加到extract_stock_volume_from_email函数中。

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注