我正在尝试逐个遍历 Pandas DataFrame 的列值,以检测符合正则表达式模式的子字符串,并在其出现的任何位置替换它。DataFrame 目标列中的字符串值具有以下变体:
- ‘函数(某物)……’
- ‘func(某物,某物)……’
我尝试使用第二种变体来定位值,并用同一行中另一列的值替换逗号分隔的子字符串。
我的示例代码如下:
import re
for i, x in enumerate(df['col1']):
df.loc[i,'col2'] = re.sub(r'^(func\().+,.+(\).*)', r'\1%s\2'%(x), df.loc[i,'col2'])
*
当我将模式中的替换为 时,终端上获得了成功的输出+
:
>>> val = 'func(y,z) and func2(a,b)'
>>> val
'func(y,z) and func2(a,b)'
>>> pattern1 = r'^(func\().+,.+(\).*)'
>>> replacement = r'\1%s\2'%('x')
>>> val2 = re.sub(pattern1, replacement, val)
>>> val2
'func(x)'
>>> pattern2 = r'^(func\().+,.+(\).+)'
>>> val2 = re.sub(pattern2, replacement, val)
>>> val2
'func(x) and func2(a,b)'
>>> val3 = 'func(y) and func2(a,b)'
>>> val4 = re.sub(pattern2, replacement, val3)
>>> val4
'func(y) and func2(a, b)'
我认为.*
inpattern1
应该能够容纳最后捕获的括号后的 0 个或更多任意字符实例\)
,但至少使用.+
inpattern2
是可行的。
问题是,当我尝试在 VSCode 上使用 Python 复制 DataFrame 的列值时,我没有得到想要的输出。我想我的正则表达式模式捕获了字符串中我不想要的部分,所以得到了混合的结果。
我遗漏了什么吗pattern2
?
更新: 这是我在 VSCode 中使用的示例代码,其中结果很有希望,但是当字符串添加更多条件时,模式就不再成立。
df = pd.DataFrame({'col1':['func(a,b) and func(c,d)','func(a) and func(c)','func(b) and func(c,d)','func(a,b,c) and func(d,e,f)'],
'col2':['e','b','a','g']})
df
>>>
col1 col2
0 func(a,b) and func(c,d) e
1 func(a) and func(c) b
2 func(b) and func(c,d) a
3 func(a,b,c) and func(d,e,f) g
import re
df['col3'] = ''
for i,x in enumerate(df['col2']):
pattern = r'^(func\().+,.+(\).+)'
replacement = fr'\1{x}\2'
df.loc[i,'col3'] = re.sub(pattern,replacement,df.loc[i,'col1'])
if df.loc[i,'col3'] != df.loc[i,'col1']:
print(df.loc[i,'col1'],'--->',df.loc[i,'col3'])
>>>
func(a,b) and func(c,d) ---> func(e) and func(c,d)
func(a,b,c) and func(d,e,f) ---> func(g) and func(d,e,f)
以上是我期望看到的,但在下面的尝试中,您可以看到附加func()
条件被删除:
df = pd.DataFrame({'col1':['func(a,b) and func(c,d) and func2(z)','func(a) and func(c) and func2(z)','func(b) and func(c,d) and func2(z)','func(a,b,c) and func(d,e,f) and func2(z)'],
'col2':['e','b','a','g']})
df
>>>
col1 col2
0 func(a,b) and func(c,d) and func2(z) e
1 func(a) and func(c) and func2(z) b
2 func(b) and func(c,d) and func2(z) a
3 func(a,b,c) and func(d,e,f) and func2(z) g
import re
df['col3'] = ''
for i,x in enumerate(df['col2']):
pattern = r'^(func\().+(?:,.+)+(\).+)'
replacement = fr'\1{x}\2'
df.loc[i,'col3'] = re.sub(pattern,replacement,df.loc[i,'col1'])
if df.loc[i,'col3'] != df.loc[i,'col1']:
print(df.loc[i,'col1'],'--->',df.loc[i,'col3'])
>>>
func(a,b) and func(c,d) and func2(z) ---> func(e) and func2(z)
func(b) and func(c,d) and func2(z) ---> func(a) and func2(z)
func(a,b,c) and func(d,e,f) and func2(z) ---> func(g) and func2(z)
该模式似乎忽略了中间的func()
表达。