Python:如何提取关键词后的数字和特定大写字母
支付老李
结论
可以用正则表达式先定位 Amount:,再捕获金额和货币代码:
r"Amount:\s*(\d+(?:\.\d+)?)\s+([A-Z]{3})"
第一个捕获组对应金额,第二个捕获组对应三位大写货币代码。
基本实现
处理单条字符串时,可以使用 re.search():
import re
text = (
"Successful refund. IBE payment ID 79104467 | "
"Transaction-ref: 73462794 | Amount: 50.00 EUR"
)
pattern = r"Amount:\s*(\d+(?:\.\d+)?)\s+([A-Z]{3})"
match = re.search(pattern, text)
if match:
amount = match.group(1)
currency = match.group(2)
print(amount) # 50.00
print(currency) # EUR
这个正则表达式可以拆成几部分理解:
Amount:匹配固定关键词。\s*允许冒号后有零个或多个空白字符。(\d+(?:\.\d+)?)捕获整数或带小数部分的金额。\s+匹配金额与货币代码之间的空白字符。([A-Z]{3})捕获由三个大写字母组成的货币代码。
提取到 Pandas 的两个独立列
数据位于 DataFrame 的文本列时,可以直接使用 str.extract():
import pandas as pd
df = pd.DataFrame({
"message": [
"Successful refund. IBE payment ID 79104467 | Transaction-ref: 73462794 | Amount: 50.00 EUR",
"Successful refund by Hyperwallet. Transaction-ref: 48886217 | Amount: 214.64 USD | Hyperwallet payout id: 581082-2",
]
})
pattern = r"Amount:\s*(\d+(?:\.\d+)?)\s+([A-Z]{3})"
df[["amount", "currency"]] = df["message"].str.extract(pattern)
print(df[["amount", "currency"]])
输出结果如下:
amount currency
0 50.00 EUR
1 214.64 USD
str.extract() 会将两个捕获组分别写入 amount 和 currency 列。某一行没有匹配结果时,这两个字段会是缺失值。
将金额转换为数值
正则提取出的金额默认是字符串。需要求和、比较或统计时,还要将它转换为数值类型:
df["amount"] = pd.to_numeric(df["amount"], errors="coerce")
设置 errors="coerce" 后,无法转换的内容会变成 NaN,方便后续检查异常数据。
如果金额可能带负号,可以把模式改为:
pattern = r"Amount:\s*(-?\d+(?:\.\d+)?)\s+([A-Z]{3})"
如果金额可能包含千位分隔符,例如 1,250.00 USD,可以使用:
pattern = r"Amount:\s*(-?[\d,]+(?:\.\d+)?)\s+([A-Z]{3})"
df[["amount", "currency"]] = df["message"].str.extract(pattern)
df["amount"] = pd.to_numeric(
df["amount"].str.replace(",", "", regex=False),
errors="coerce"
)
注意事项
[A-Z]{3} 适用于货币代码始终由三个大写字母组成的情况,例如 EUR、USD。如果输入中可能出现小写代码,可以忽略大小写进行匹配:
df[["amount", "currency"]] = df["message"].str.extract(
pattern,
flags=re.IGNORECASE
)
df["currency"] = df["currency"].str.upper()
不要直接匹配字符串中的任意数字。示例文本里还有支付 ID、交易编号和付款编号,使用 Amount: 定位,才能避免误提取这些数字。
备注:内容仅供参考。
