我是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
函数中。