正则表达式匹配字符串中的多个数字

Regex to match multiple numbers within string

我有一个看起来像这样的正则表达式来从列中提取订单号:

df["Orders"].str.extract('([0-9]{9,10}[/+ #_;.-]?)')

订单列可能如下所示:

12
123456789
1234567890
123456789/1234567890
123456789/1/123456789
123456789+1234567890

数据框中在正则表达式之后生成的新列应如下所示:

NaN
123456789
1234567890
123456789/1234567890
123456789/123456789
123456789+1234567890

但是,使用我当前的正则表达式,我得到以下结果:

NaN
123456789
1234567890
123456789/
123456789/
123456789+

我怎样才能得到我正在寻找的结果?

你可以使用

import pandas as pd
df = pd.DataFrame({'Orders':['12','123456789','1234567890','123456789/1234567890','123456789/1/123456789','123456789+1234567890', 'Order number: 6508955960_000010_1005500']})
df["Result"] = df["Orders"].str.findall(r'[/+ #_;.-]?(?<![0-9])[0-9]{9,10}(?![0-9])').str.join('').str.lstrip('/+ #_;.-')
df.loc[df['Result'] == '', 'Result'] = np.nan

参见regex demo详情

  • [/+ #_;.-]?(?<![0-9])[0-9]{9,10}(?![0-9]) - 匹配可选的 /+、space、#_;.- 字符,然后是 none 或不包含其他数字的十位数字
  • Series.str.findall 提取所有出现的地方
  • .str.join('') 将匹配项连接成一个字符串
  • .str.lstrip('/+ #_;.-') - 删除与字符串开头的数字匹配的特殊字符
  • df.loc[df['Result'] == '', 'Result'] = np.nan - 如果需要 - 用 Result 列中的 np.nan 值替换空字符串。

输出:

>>> df
                  Orders                Result
0                    NaN                   NaN
1              123456789             123456789
2             1234567890            1234567890
3   123456789/1234567890  123456789/1234567890
4  123456789/1/123456789   123456789/123456789
5   123456789+1234567890  123456789+1234567890
>>> 

您可以调整下一个代码以处理数据框,

正则表达式:(?:^|([/+ #_;.-]))(?:\d{1,8})(?!\d)

  • (?:\d{1,8})(?!\d) - 查找号码(<9 位)
  • ([/+ #_;.-]) - 前面有 one/none 个可能的分隔符(第 1 组)

有条件地替换为 NaN 或空字符串 - subst 使用 match.group(1) 来区分两个选项:

  • standalone-invalid - 12
  • invalid-with-delimiter - /1
import re

regex = r"(?:^|([/+ #_;.-]))(?:\d{1,8})(?!\d)"

test_str = ("12\n"
            "123456789\n"
            "1234567890\n"
            "123456789/1234567890\n"
            "123456789/1/123456789\n"
            "123456789+1234567890")

def subst(match):
    m = match.group(1)
    return "" if m else "NaN"

result = re.sub(regex, subst, test_str, 0, re.MULTILINE)

if result:
    print(result)

输出:

NaN
123456789
1234567890
123456789/1234567890
123456789/123456789
123456789+1234567890