正则表达式匹配字符串中的多个数字
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
我有一个看起来像这样的正则表达式来从列中提取订单号:
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