使用正则表达式替换python中字符串的一部分

使用正则表达式替换python中字符串的一部分,python,regex,Python,Regex,我想要的是: 原始字符串:(#1和#12)或#10 转换为:(某物和另一个某物)或另一个某物 意思是说,根据#number用唯一的字符串替换它 我所做的是: filter_string = "(#1 AND #12) OR #10" for fltr in filters_array: index = fltr[0] #numbers coming from here replace_by = fltr[1] #this string will replace o

我想要的是:
原始字符串:
(#1和#12)或#10

转换为:
(某物和另一个某物)或另一个某物

意思是说,根据
#number
用唯一的字符串替换它

我所做的是:

filter_string = "(#1 AND #12) OR #10"
for fltr in filters_array:
        index = fltr[0] #numbers coming from here
        replace_by = fltr[1] #this string will replace original one
        filter_string = re.sub(r'#'+str(index),replace_by,filter_string)
输出:

(something AND something2) OR something0
问题是:与其说它取代了#1,不如说它取代了#12和#11,还因为#12也有#1。

我在
re.sub()
函数中尝试了
count=1
,但它不起作用,因为我的字符串也可以是“
(#12和#1)
”。

使用单词边界
\\b
锚定强制进行精确的数字匹配:

filter_string = "(#1 AND #12) OR #10"
filters_array = [(1,"something"),(10,"something_another"),(12,"another_somet‌​hing")]
for num,s in filters_array:
    filter_string = re.sub(r'#'+ str(num) +'\\b', s, filter_string)

print(filter_string)
输出:

(something AND another_somet‌​hing) OR something_another

使用单词边界
\\b
锚定强制精确数字匹配:

filter_string = "(#1 AND #12) OR #10"
filters_array = [(1,"something"),(10,"something_another"),(12,"another_somet‌​hing")]
for num,s in filters_array:
    filter_string = re.sub(r'#'+ str(num) +'\\b', s, filter_string)

print(filter_string)
输出:

(something AND another_somet‌​hing) OR something_another

您可以将元组列表转换为字典,并使用带有捕获数字部分的模式的
re.sub
,然后在替换参数中使用lambda表达式按键查找正确的值:

import re
filter_string = "(#1 AND #12) OR #10"
filters_array = [(1,"something"),(10,"something_another"),(12,"another_something")]
dt = dict(filters_array)
filter_string = re.sub(r'#([0-9]+)', lambda x: dt[int(x.group(1))] if int(x.group(1)) in dt else x.group(), filter_string)
print(filter_string)
# => (something AND another_something) OR something_another
#([0-9]+)
模式匹配
#
,然后匹配并捕获到组1中的一个或多个数字。然后,在lambda内部,使用数值获取现有值。如果该数字不存在,则将该数字重新插入结果中

如果需要进一步处理匹配,您可能希望在替换参数中使用回调方法而不是lamda:

import re

filters_array = [(1,"something"),(10,"something_another"),(12,"another_something")]
dt = dict(filters_array)

def repl(m):
    return dt[int(m.group(1))] if int(m.group(1)) in dt else m.group()

filter_string = re.sub(r'#([0-9]+)', repl, "(#1 AND #12) OR #10")
print(filter_string)

请参阅。

您可以将元组列表转换为字典,并使用带有捕获数字部分的模式的
re.sub
,然后在替换参数中使用lambda表达式按键查找正确的值:

import re
filter_string = "(#1 AND #12) OR #10"
filters_array = [(1,"something"),(10,"something_another"),(12,"another_something")]
dt = dict(filters_array)
filter_string = re.sub(r'#([0-9]+)', lambda x: dt[int(x.group(1))] if int(x.group(1)) in dt else x.group(), filter_string)
print(filter_string)
# => (something AND another_something) OR something_another
#([0-9]+)
模式匹配
#
,然后匹配并捕获到组1中的一个或多个数字。然后,在lambda内部,使用数值获取现有值。如果该数字不存在,则将该数字重新插入结果中

如果需要进一步处理匹配,您可能希望在替换参数中使用回调方法而不是lamda:

import re

filters_array = [(1,"something"),(10,"something_another"),(12,"another_something")]
dt = dict(filters_array)

def repl(m):
    return dt[int(m.group(1))] if int(m.group(1)) in dt else m.group()

filter_string = re.sub(r'#([0-9]+)', repl, "(#1 AND #12) OR #10")
print(filter_string)

请参阅。

您的
过滤器数组是什么样子的?
类似于[(1,“某物”),(10,“某物”;(12,“另一物”)]尝试
re.sub(r'.'+str(index)+'$',替换为过滤器字符串)
$
匹配字符串的结尾。不,但它不是字符串的结尾,也可以是(#12和#1)。因此,在#number as colsing brace')之后可能会出现一个空格。你的
过滤器数组
是什么样子的?它就像[(1,“某物”),(10,“某物”),(12,“另一物”)]尝试
re.sub(r'.'.'+str(index)+'$”,用过滤器字符串替换
$
匹配字符串的结尾。不,但它不是字符串的结尾,也可以是(#12和#1)。所以在#number as colsing brace')之后,同样可能存在一个空格。但是这种方法有效吗?@rajsah:注意,使用这种方法,字符串只被替换一次。使用循环时,修改字符串的次数与
过滤器\u数组中的项目的次数相同。另请注意:正则表达式可能是
r'#([0-9]+)\b'
,具体取决于要求。我的字符串只有唯一的数字。所以没问题。@rajsah如果您有100个数字,您希望将字符串更改100次,还是只更改一次?当然,这取决于您。@RomanPerekhrest那么回调比lambda更合适,但这种方法更有效。我尝试了这段代码,它成功了。但是这种方法有效吗?@rajsah:注意,使用这种方法,字符串只被替换一次。使用循环时,修改字符串的次数与
过滤器\u数组中的项目的次数相同。另请注意:正则表达式可能是
r'#([0-9]+)\b'
,具体取决于要求。我的字符串只有唯一的数字。所以没问题。@rajsah如果您有100个数字,您希望将字符串更改100次,还是只更改一次?当然,这取决于您自己。@RomanPerekhrest那么回调比lambda更合适,但这种方法更有效。