python - 模式匹配句子中的多个值
问题描述
我有一个具有特定格式的句子。
<subject> <action> <object> @ <price> ... // The sentence can continue
我想从句子中提取这些值。
约束:
- 主题总是
Bob
或Alice
- 行动要么是
bought
要么sold
- 对象可以是 1-7 个字母的任何单词 //
4apples
应该返回 NULL - 价格是浮点数/整数
- 前面可以有句子,
subject
但保证不包含Bob/Alice
. - 后面可能有也可能没有空格
@
例子:
Hi there, Bob sold apples @2.0 dollars each
期望的输出:
Subject: Bob
Action: sold
Object: apples
Price: 2.0
目前,我通过以下方式以天真的方式做到这一点:
#!/usr/bin/env python3
sentence = "Hi there, alice sold apples @2.0 dollars each"
sentence = sentence.lower()
if 'alice' in sentence or 'bob' in sentence:
s_list = sentence.split(" ")
s_idx = -1
if 'bob' in sentence:
s_idx = s_list.index('bob')
elif 'alice' in sentence:
s_idx = s_list.index('alice')
if s_idx > -1:
Subject = s_list[s_idx]
Action = s_list[s_idx+1]
Object = s_list[s_idx+2] #more if/else to validate Object contraints
Price = s_list[s_idx+3] #more if/else to extract 2.0 if we get @2.0
print("Subject: {}, Action: {}, Object: {}, Price: {}".format(Subject, Action, Object, Price))
我怎样才能做得更好?可能使用re
解决方案
您可以为每个元素使用带有命名捕获组的正则表达式:
import re
sentence = "Hi there, alice sold apples @2.0 dollars each"
values = re.search('(?P<subject>bob|alice)\s+(?P<action>bought|sold)\s+(?P<object>[A-Za-z]{1,7})\s+@\s*(?P<price>\d+(?:\.\d+)?)', sentence)
if values:
Subject = values['subject']
Action = values['action']
Object = values['object']
Price = values['price']
print("Subject: {}, Action: {}, Object: {}, Price: {}".format(Subject, Action, Object, Price))
这将输出
Subject: alice, Action: sold, Object: apples, Price: 2.0
请注意,您可能希望提供re.I
标志以re.search
允许匹配bob
或Bob
(或Sold
或等);sold
在这种情况下,您可以[A-Za-z]
在object
捕获组中替换为[a-z]
.
推荐阅读
- ios - 如何在 Firebase 动态链接预览页面设置 logo 图标?
- python - 使用 Pandas 基于列的唯一值创建 DataFrame,然后为创建的每个 DF 导出到 excel
- angular - 在 FormArray Angular 8 中获取总数
- c - 返回 0,错误代码 6,C++ 中的 OpenProcess()
- c - fgets() 没有在 c 中保存第一行
- flutter - 用颤振连接到 wifi
- windows - 如何通过堡垒从客户端计算机在私有 Windows 计算机中运行 Powershell 脚本
- python - 如何在python中计算多边形的截面积
- python - python数学结果与python结果和计算器不同
- html - 根据位置值,应用于伪元素的背景的不同行为