python. re.findall 和 re.sub 的 '^' 使用

0 投票
2 回答
1025 浏览
提问于 2025-04-17 23:48

我想把一个字符串,比如 s='2.3^2+3^3-√0.04*2+√4',进行一些修改,具体来说:

其中,2.3^2 要改成 pow(2.3,2),3^3 要改成 pow(3,3),√0.04 要改成 sqrt(0.04),而 √4 则要改成 sqrt(4)。

s='2.3^2+3^3-√0.04*2+√4'
patt1='[0-9]+\.[0-9]+\^[0-9]+|[0-9]+\^[0-9]'
patt2='√[0-9]+\.[0-9]+|√[0-9]+'
idx1=re.findall(patt1, s)
idx2=re.findall(patt2, s)
idx11=[]
idx22=[]
for i in range(len(idx1)):
    idx11.append('pow('+idx1[i][:idx1[i].find('^')]+','+idx1[i][idx1[i].find('^')+1:]+')')

for i in range(len(idx2)):
    idx22.append('sqrt('+idx2[i][idx2[i].find('√')+1:]+')')

for i in range(len(idx11)):
    s=re.sub(idx1[i], idx11[i], s)

for i in range(len(idx22)):
    s=re.sub(idx2[i], idx22[i], s)

print(s)

临时结果:

idx1=['2.3^2', '3^3']

idx2=['√0.04', '√4']

idx11=['pow(2.3,2)', 'pow(3,3)']

idx22=['sqrt(0.04)', 'sqrt(4)']

但是最后得到的字符串结果是:

2.3^2+3^3-sqrt(0.04)*2+sqrt(4)

为什么计算出的 'idx1' 是正确的,但在用 re.sub 的时候却没有把这些值插入到字符串里呢?

(抱歉我的英语不好:)

2 个回答

0

我只有 Python 2.7.5,但这个方法对我有效,我用的是 str.replace 而不是 re.sub。一旦你找到了匹配的内容并构造了替换的内容,这就只是一个简单的查找和替换的工作:

for i in range(len(idx11)):
    s = s.replace(idx1[i], idx11[i])

for i in range(len(idx22)):
    s = s.replace(idx2[i], idx22[i])

编辑

我觉得你这样做有点绕。你可以直接用 re.sub 一步到位地进行这些更改:

s = re.sub('(\d+(\.\d+)?)\^(\d+)', r'pow(\1,\3)', s)

这将把 2.3^2+3^3 替换成 pow(2.3,2)+pow(3,3),并且:

s = re.sub('√(\d+(\.\d+)?)', r'sqrt(\1)', s)

这将把 √0.04*2+√4 替换成 sqrt(0.04)*2+sqrt(4)

这里有几个不同的地方。首先,\d 是用来匹配数字的,和 [0-9] 是一样的。其次,( ) 用来捕获里面的内容。在替换时,你可以通过它们出现的顺序来引用这些捕获的组。在 pow 的例子中,我用的是我捕获的第一组和第三组。

在替换字符串前加上 r 表示这个字符串是“原始的”,所以字符会被字面理解。访问这些组时用 \1\2 等,但因为反斜杠 \ 是一个转义字符,所以如果没有 r 的话,我每次都得转义它(\\1\\2 等)。

2

试试只用 re.sub() 来实现这个功能

输入字符串:

s='2.3^2+3^3-√0.04*2+√4'

替换为 pow()

s = re.sub("(\d+(?:\.\d+)?)\^(\d+)", "pow(\\1,\\2)", s)

替换为 sqrt()

s = re.sub("√(\d+(?:\.\d+)?)", "sqrt(\\1)", s)

输出:

pow(2.3,2)+pow(3,3)-sqrt(0.04)*2+sqrt(4)

() 表示一个分组捕获,而 \\1 表示正则表达式匹配到的第一个分组。你可以通过这个链接获取正则表达式的详细解释。

撰写回答