1

我正在尝试编写一个正则表达式,以确保根据规范正确重新格式化“标签”。(我正在更新一堆遗留的东西。)

一般的想法是标签可以在()或中包含括号内容[]。但是,现有标签可能格式不正确:

  • 好的 :
    • Sample (sample)
    • Sample [sample]
  • 坏的 :
    • Sample (( sample )
    • Sample [(sample]]

我目前正在使用一系列正则表达式来处理这个问题,但我想知道在技术上是否可以一次性完成。

在代码的简化版本中......

RE_tag_collapse = re.compile(\
    """
        ([\[\(])+               ### opening bracket
            \s*
            (                   # the contents
                [^\]\)]+
            )
            \s*
        ([\]\)])*               # closing bracket
    """
    ,
    re.I | re.VERBOSE
)
edited= re.sub( RE_tag_collapse , r'\1\2\1' , tag )

这个正则表达式的问题是结束标记(第二个\1)与开始标记相同。

我想要做的是将结束标签映射为开始标签的倒数:

  • (反转为)
  • [反转为]

有谁知道这是否容易实现?在我看来,我最好的解决方案是保持原样并使用多个正则表达式。

4

2 回答 2

2

如果我正确理解您的问题,您需要确保标签中的括号匹配。据我所知,python中的正则表达式无法计算出现次数。但是,您可以使用一个函数来检查括号是否匹配,如下所示:

def check_tag(tag):
    charstack = []
    for c in tag:
        if c in ["(","]"]:
            charstack.append(c)
        else if c in [")","]"]:
            popped = charstack.pop()
            if not ((c == ")" and popped == "(" ) or (c == "]" and popped == "[")):
                return False
    return len(charstack) == 0

这个函数的工作方式是,每次它找到一个左括号时,它就会将它压入堆栈。每次遇到右括号时,它都会将一个元素推出堆栈以查看它们是否匹配。如果他们不这样做,则标签格式不正确。

于 2012-08-31T22:30:39.740 回答
2

修改您的正则表达式以将所有左括号和右括号捕获为组,然后您可以从左括号集中生成正确的右括号集并在正则表达式替换中使用它

像这样:

>>> def subber(matchobj):
    return ' '.join([matchobj.group(1),
             matchobj.group(2),
             matchobj.group(1).replace('[',']').replace('(', ')')[::-1]])

>>> new_RE = re.compile(\
    """
        ([\[\(]+)               ### opening brackets
            \s*
            (                   # the contents
                [^\]\)]+
            )
            \s*
        ([\]\)]+)               # closing brackets
    """
    ,
    re.I | re.VERBOSE
)
>>> txt = 'Sample [(sample]]'
>>> new_RE.sub(subber, txt)
'Sample [( sample )]'
>>> 

右括号只是将每个左括号替换为捕获左括号的组中的右括号,然后将其反转。

于 2012-09-01T10:01:09.333 回答