str.extract() 与正则表达式
Posted
技术标签:
【中文标题】str.extract() 与正则表达式【英文标题】:str.extract() with regex 【发布时间】:2022-01-20 12:21:35 【问题描述】:我需要使用正则表达式和str.extract()
将一列分成两部分(假设这是最好的)
df = pd.DataFrame(
'Product': ['Truly Mix 2/12Pk Cans - 12Z',
'Bud 16Z - LOOSE - 16Z',
'Blue Moon (Case 12x - 22Z)',
'2 for the show (6/4PK - 16Z)']
)
我想要这个结果:
df_result = pd.DataFrame(
'Product': ['Truly Mix', 'Bud', 'Blue Moon', '2 for the show'],
'Packaging': ['2/12Pk Cans - 12Z',
'16Z - LOOSE - 16Z',
'Case 12x - 22Z',
'6/4PK - 16Z' ]
)
我尝试了很多东西,但仍然在使用正则表达式时遇到了困难,即使经过大量的在线学习。
这是我获得产品的最后尝试:
pattern = r'(\D+)[^\w][^(Case][^0-9]'
df['Product'] = df['Product'].str.extract(pattern)
str.replace()
应该可以很好地摆脱括号,只是不能走那么远。
我只是在 3 小时后还没有关闭。
【问题讨论】:
【参考方案1】:您可以将每个条目的两个部分提取到两列中,然后在它们所在的字符串的开头/结尾删除(
和)
:
import pandas as pd
df = pd.DataFrame('Product': ['Truly Mix 2/12Pk Cans - 12Z','Bud 16Z - LOOSE - 16Z','Blue Moon (Case 12x - 22Z)','2 for the show (6/4PK - 16Z)'])
pattern = r'^(.*?)\s*((?:\((?:Case\b)?|\d+(?:/\d+)?[A-Za-z]+\b).*)'
df[['Product', 'Packaging']] = df['Product'].str.extract(pattern, expand=True)
df['Packaging'] = df['Packaging'].str.replace(r'^\((.*)\)$', r'\1', regex=True)
# => >>> print(df['Packaging'])
# 0 2/12Pk Cans - 12Z
# 1 16Z - LOOSE - 16Z
# 2 Case 12x - 22Z
# 3 6/4PK - 16Z
# => >>> print(df['Product'])
# 0 Truly Mix
# 1 Bud
# 2 Blue Moon
# 3 2 for the show
请参阅regex demo。 正则表达式详细信息:
^
- 字符串开头
(.*?)
- 第 1 组:除换行符之外的任何零个或多个字符尽可能少
-\s*
- 零个或多个空格
((?:\((?:Case\b)?|\d+(?:/\d+)?[A-Za-z]+\b).*)
- 第 2 组:
(?:\((?:Case\b)?|\d+(?:/\d+)?[A-Za-z]+\b)
- 任何一个
\((?:Case\b)?
- 一个(
,然后是一个可选的整个单词Case
|
- 或
\d+(?:/\d+)?[A-Za-z]+\b
- 一个或多个数字,/
和一个或多个数字的可选序列,以及一个或多个字母(后跟单词边界)
.*
- 除换行符之外的任何零个或多个字符尽可能多
.replace(r'^\((.*)\)$', r'\1', regex=True)
部分删除了字符串开头和结尾处的(
和)
。
【讨论】:
以上是关于str.extract() 与正则表达式的主要内容,如果未能解决你的问题,请参考以下文章