替换括在花括号中的逗号

时间:2016-01-14 10:37:38

标签: python json regex python-3.x

我尝试用括号括起来的分号替换逗号。

示例字符串:

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

知道如何实现这一目标吗? 任何帮助非常感谢:)

3 个答案:

答案 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在本帖末尾对测试字符串提出的正则表达式解决方案时,我得到以下时间:

  1. 正则表达式(@stribizshev):0.38秒
  2. 地图功能:26.3秒
  3. For循环:251秒
  4. 这是长度为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介于两者之间。搜索

,(?=[^{]*})

并替换为;

As explained in the docs