在python中替换没有清晰模式的不同子字符串

在python中替换没有清晰模式的不同子字符串,python,string,replace,Python,String,Replace,我需要替换某些查询(字符串)的一部分,这些查询不总是有相同的子字符串要替换 query = """ SELECT DATE(utimestamp) as utimestamp, sum(value) as value from table where utimestamp BETWEEN '2000-06-28 00:00:00' AND '2000-07-05 00:00:00' group by YEAR(utimestamp), MONTH(utimestamp), id """

我需要替换某些查询(字符串)的一部分,这些查询不总是有相同的子字符串要替换

query = """ SELECT DATE(utimestamp) as utimestamp, sum(value) as value 
from table 
where utimestamp BETWEEN '2000-06-28 00:00:00' AND '2000-07-05 00:00:00' 
group by YEAR(utimestamp), MONTH(utimestamp), id """
我想在分组后替换有关日期的部分

此部分可以是以下任意字符串:

'YEAR(utimestamp), MONTH(utimestamp), DAY(utimestamp),'
'YEAR(utimestamp), MONTH(utimestamp), WEEK(utimestamp),'
'YEAR(utimestamp), MONTH(utimestamp),'
'YEAR(utimestamp),'
我的想法是搜索“(utimestamp),”并从左侧(年、日、周或月)获取零件,搜索左侧的第一个空格。删除这些子字符串后,我想插入另一个子字符串,但既然新的子字符串应该放在空白处,如何插入此子字符串呢

我想每次删除一个字符串时都会得到索引,一旦不再需要删除,就在那里插入子字符串,但我认为这会使事情复杂化

有没有更简单、简洁的方法?我错过什么了吗

示例:

需要替换的输入字符串:

query=“”选择日期(utimestamp)作为utimestamp,选择总和(值)作为值 从桌子上 其中utimestamp位于“2000-06-28 00:00:00”和“2000-07-05 00:00:00”之间 按年份(utimestamp)、月份(utimestamp)、id“”分组

等等

预期结果:

query_replaced = """ SELECT DATE(utimestamp) as utimestamp, sum(value) as value 
    from table 
    where utimestamp BETWEEN '2000-06-28 00:00:00' AND '2000-07-05 00:00:00' 
    group by MY_COOL_STRING, id """
If应适用于所有这些情况(以及之前所述的更多情况)

根据@efferagan的回答,我得出了以下结论:

query_1 = query.split("group by")[0]
utimestamp_list = query.split("(utimestamp)")
l = len(utimestamp_list)
query_2 = utimestamp_list[l-1]
query_3 = query_1 + " group by MY_COOL_STRING" + query_2
您可以使用正则表达式来实现它:

>>> import re
>>> replace_with = 'HELLO'
>>> new_string  = re.sub('group by\s\w+\(utimestamp\)', "group_by"+replace_with, query)

# Value of new_string: SELECT  as utimestamp, sum(value) as value 
# from table 
# where utimestamp BETWEEN '2000-06-28 00:00:00' AND '2000-07-05 00:00:00' 
# group by HELLO, HELLO, id
其中,
replace\u with
是您需要使用模式
'\w+\(utimestamp\)
更新的内容,
query
是您在代码中提到的字符串

在这里,
\w+
表示出现一个或多个字母的字母表,而
\(utimestamp\)
以及它表示后跟字符串的单词
(utimestamp)

编辑

如注释中所述,要替换
查询
中的
时间戳
的所有实例,正则表达式应如下所示:

re.sub('group by\s\w+\(utimestamp\)(,\s*\w+\(utimestamp\))*', "group_by" + replace_with, query)

# Returned Value:  
# SELECT DATE(utimestamp) as utimestamp, sum(value) as value from table
# where utimestamp BETWEEN '2000-06-28 00:00:00' AND '2000-07-05 00:00:00'
# group by HELLO, id
您可以使用正则表达式来实现它:

>>> import re
>>> replace_with = 'HELLO'
>>> new_string  = re.sub('group by\s\w+\(utimestamp\)', "group_by"+replace_with, query)

# Value of new_string: SELECT  as utimestamp, sum(value) as value 
# from table 
# where utimestamp BETWEEN '2000-06-28 00:00:00' AND '2000-07-05 00:00:00' 
# group by HELLO, HELLO, id
其中,
replace\u with
是您需要使用模式
'\w+\(utimestamp\)
更新的内容,
query
是您在代码中提到的字符串

在这里,
\w+
表示出现一个或多个字母的字母表,而
\(utimestamp\)
以及它表示后跟字符串的单词
(utimestamp)

编辑

如注释中所述,要替换
查询
中的
时间戳
的所有实例,正则表达式应如下所示:

re.sub('group by\s\w+\(utimestamp\)(,\s*\w+\(utimestamp\))*', "group_by" + replace_with, query)

# Returned Value:  
# SELECT DATE(utimestamp) as utimestamp, sum(value) as value from table
# where utimestamp BETWEEN '2000-06-28 00:00:00' AND '2000-07-05 00:00:00'
# group by HELLO, id

根据你的要求,我会去的

query = query.split("group by")[0] + " group by MY_COOL_STRING" + query.split("(utimestamp)")[-1]

它通过将
分组之前的部分连接起来,然后是
我的COOL\u字符串
,然后是第一个
(utimestamp)
,根据您的要求,我会选择

query = query.split("group by")[0] + " group by MY_COOL_STRING" + query.split("(utimestamp)")[-1]

它通过
组前面的部分连接起来,然后是
我的COOL\u字符串
,然后是第一个
(utimestamp)
前面的第一件事如果我没弄错的话,你不想去掉
(utimestamp)
部分,只想去掉
,等等,或者可能是我弄错了,但这种解决方案在这种情况下很难适应:只需调整
rep
dict来满足您的需要

在任何情况下,我都会使用正则表达式。这应该在一次通过中以一种(相当)简单的方式照顾到您想要的(我认为)

重新导入
代表={
“年”:“y”,
“月”:“m”,
“周”:“w”,
“DAY”:“d”,
}
query=“”从表中选择日期(utimestamp)作为utimestamp,总和(值)作为值
其中utimestamp位于“2000-06-28 00:00:00”和“2000-07-05 00:00:00”之间
按年份(utimestamp)、月份(utimestamp)、id“”分组
rep=dict((在rep.iteritems()中对k,v进行转义(k,v))
pattern=re.compile(“|”).join(rep.keys())
替换=pattern.sub(lambda m:rep[re.escape(m.group(0))],查询)
打印(“已处理的查询:{}\n.”格式(已替换))
这只是一个基本的例子。下面是一个更完整的注释,解释了代码的功能,包括在末尾测试您提到的所有可能模式:

重新导入
#像你提到的几种可能的模式。
#仅用于进一步测试。
模式=[
“年(utimestamp)、月(utimestamp)、日(utimestamp)”,
“年(utimestamp)、月(utimestamp)、周(utimestamp)”,
“年(utimestamp),月(utimestamp)”,
‘年份(utimestamp)’
]
#这些是要匹配的几个模式及其替换。
#键是要匹配的模式,值是您想要的
#用……代替它们。
代表={
“年”:“y”,
“月”:“m”,
“周”:“w”,
“DAY”:“d”,
}
#查询字符串模板,其中我们将用每个模式替换{}。
query=“”从表中选择日期(utimestamp)作为utimestamp,总和(值)作为值
其中utimestamp位于“2000-06-28 00:00:00”和“2000-07-05 00:00:00”之间
分组依据{},id”“”
#带有转义模式(键)的字典,适合在正则表达式中使用。
rep=dict((在rep.iteritems()中对k,v进行转义(k,v))
#我们用|连接每个可能的模式(rep dict中的键),以便
#正则表达式引擎在匹配时会考虑它们,即,“嘿,正则表达式引擎,
#请匹配年或月或周或日”。这建立了匹配的模式
#我们将使用并预编译正则表达式,以加快速度。
pattern=re.compile(“|”).join(rep.keys())
#这是诀窍:我们使用pattern.sub()替换来自的模式
#上面是我们想要的(rep dict中的值)。我们正在告诉正则表达式
#引擎为模式的每次出现调用一个函数,以便
#我们正在用它替换的值。在我们的例子中,我们希望从
#rep dict,使用找到的匹配项的键。m是匹配对象,
#m.group(0)是第一个匹配项,re.escape()将对该值进行转义,最后
#使用此键从rep dict获取值。
q=query.format(模式[0])
打印(“查询: