我尝试用括号括起来的分号替换逗号。
示例字符串:
text = "a,b,{'c','d','e','f'},g,h"
我知道它归结为外观和前瞻,但不知怎的,它不会像我想要的那样工作:
substr = re.sub(r"(?<=\{)(.+?)(,)(?=.+\})",r"\1;", text)
它返回:
a,b,{'c';'d','e','f'},g,h
但是,我的目标是:
a,b,{'c';'d';'e';'f'},g,h
知道如何实现这一目标吗? 任何帮助非常感谢:)
答案 0 :(得分:3)
您可以匹配整个块{...}
(使用{[^{}]+}
)并将其中的逗号替换为lambda:
import re
text = "a,b,{'c','d','e','f'},g,h"
print(re.sub(r"{[^{}]+}", lambda x: x.group(0).replace(",", ";"), text))
请参阅IDEONE demo
输出:a,b,{'c';'d';'e';'f'},g,h
通过声明lambda x
,我们可以访问每个匹配对象,并使用x.group(0)
获取整个匹配值。然后,我们需要的是用分号替换逗号。
此正则表达式不支持递归模式。要使用递归模式,您需要PyPi regex module。像m = regex.sub(r"\{(?:[^{}]|(?R))*}", lambda x: x.group(0).replace(",", ";"), text)
这样的东西应该有效。
答案 1 :(得分:2)
下面我发布了一个不依赖于正则表达式的解决方案。它使用堆栈(list
)来确定字符是否在大括号{
内。正则表达式更优雅,但是,当需求更改时,它们可能更难修改。请注意,下面的示例也适用于嵌套括号。
text = "a,b,{'c','d','e','f'},g,h"
output=''
stack = []
for char in text:
if char == '{':
stack.append(char)
elif char == '}':
stack.pop()
#Check if we are inside a curly bracket
if len(stack)>0 and char==',':
output += ';'
else:
output += char
print output
这给出了:
'a,b,{'c';'d';'e';'f'},g,h
如果您使用map
的全局变量,也可以将其重写为stack
函数:
stack = []
def replace_comma_in_curly_brackets(char):
if char == '{':
stack.append(char)
elif char == '}':
stack.pop()
#Check if we are inside a curly bracket
if len(stack)>0 and char==',':
return ';'
return char
text = "a,b,{'c','d','e','f'},g,h"
print ''.join(map(str, map(replace_comma_in_curly_brackets,text)))
关于性能,当运行上述两个方法和@stribizhev在本帖末尾对测试字符串提出的正则表达式解决方案时,我得到以下时间:
这是长度为55,300,00个字符的测试字符串:
text = "a,able,about,across,after,all,almost,{also,am,among,an,and,any,are,as,at,be,because},been,but,by,can,cannot,could,dear,did,do,does,either,else,ever,every,for,from,get,got,had,has,have,he,her,hers,him,his,how,however,i,if,in,into,is,it,its,just,least,let,like,likely,may,me,might,most,must,my,neither,no,nor,not,of,off,often,on,only,or,other,our,own,rather,said,say,says,she,should,since,so,some,than,that,the,their,them,then,there,these,they,this,tis,to,too,twas,us,wants,was,we,were,what,when,where,which,while,who,whom,why,will,with,would,yet,you,your" * 100000
答案 2 :(得分:1)
如果您没有嵌套大括号,如果前方有,
结束而没有任何开放{}
,则每{
个look ahead可能就足够了lookahead介于两者之间。搜索
,(?=[^{]*})
并替换为;
,
字面匹配逗号(?=
... )
any amount要检查[^{]*
that are not个字符,See demo at regex101 {
}