PAYATHON 2026

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: 定位,才能避免误提取这些数字。

备注:内容仅供参考。