使用正则表达式删除格式字符串

时间:2014-02-09 16:27:11

标签: python regex

我有一个字符串格式:

(header1:content1(note1, note2),content2(note3),content3)-(header2:content)-(header3)

现在我要删除所有内容,我想要的预期输出是

(header1)-(header2)-(header3)

我该怎么做?我尝试了一些正则表达式,但输出不正确。

更新1: headercontentnote可以包含除()之外的任何字符。

更新2: @adsmith解决了我原来的问题。现在我的字符串格式如下:

normalcontent1-(header1:content1(note1, note2),content2(note3),content3)-(header2:content)-normalcontent2-(header3)

预期产出:

normalcontent1-(header1)-(header2)-normalcontent2-(header3)

2 个答案:

答案 0 :(得分:1)

以下是pyparsing的示例:

import pyparsing as pp
import re

txt='''normalcontent1-(header1:content1(note1, note2),content2(note3),content3)-(header2:content)-normalcontent2-(header3)
normalcontent1-(header:content)-normalcontent2-normalcontent3-(header2:content2‌​)'''

def DashSplit(txt):
    ''' Replicate the function of str.split(',') but do not split on nested expressions or in quoted strings'''
    com_lok=[]
    dash = pp.Suppress('-')
    # note the location of each dash outside an ignored expression:
    dash.setParseAction(lambda s, lok, toks: com_lok.append(lok))
    ident = pp.Word(pp.alphas+"_", pp.alphanums+"_")  # python, C type identifier
    exp=(pp.nestedExpr())                             # Ignore everthing inside nested '( )'

    atom = ident | exp 
    expr = pp.OneOrMore(atom) + pp.ZeroOrMore(dash  + atom )
    try:
        result=expr.parseString(txt)
    except pp.ParseException as e:
        print('nope', e)
        return [txt]
    else:    
        return [txt[st:end] for st,end in zip([0]+[e+1 for e in com_lok],com_lok+[len(txt)])]      

def headerGetter(txt):
    m=re.match(r'\((\w+)', txt)
    if m:
        return '('+re.match(r'\((\w+)', txt).group(1)+')' 
    else:
        return txt    

for line in txt.splitlines():    
    print('-'.join(headerGetter(e) for e in DashSplit(line))) 

打印:

normalcontent1-(header1)-(header2)-normalcontent2-(header3)
normalcontent1-(header)-normalcontent2-normalcontent3-(header2)

如果你正确定义了你的语法,解析器将是一个比正则表达式更强大的解决方案。

答案 1 :(得分:0)

def getheaders(text):
    elements = re.split("(?<=\))-",text)
    return '-'.join(["("+header.split(":")[0].strip("()")+")" for header in elements])

text = "(header1:content1(note1, note2),content2(note3),content3)-(header2:content)-(header3)"
getheaders(text)
>>> '(header1)-(header2)-(header3)'

请注意,如果header包含:,则会失败,因此如果出现错误,您可能需要手动解析这些案例。如果我不能从内容中划分标题,我没有一个很好的解决方案,抱歉。如果内容不能:你只能split(":")[:-2],但如果标题和内容都包含:那么就不可能(以编程方式)说明标题结束的位置和内容开始。