【问题标题】:Regex match with negative lookbehind, recursive pattern and negative lookahead正则表达式匹配负后瞻、递归模式和负前瞻
【发布时间】:2021-01-05 11:49:44
【问题描述】:

我需要匹配这个:

void function{ {  {  } }}   

(带平衡括号的函数定义) 但不是这个

static stTLookupTable RxTable[MAX]={
     
    {zero, one},{zero, one},{zero, one}};

我尝试使用(?<![[=])({((?>[^{}]+|(?R))*)})(?!;) 匹配外观 但这与变量声明中的 {zero, one} 匹配。

(?<![[=]){((?>[^{}]+|(?R))*)}[^;]$ doesn't work either.

简而言之,我需要它来匹配函数定义,而不是数组声明,假设数组初始化以]= 开头。 有谁知道如何单独匹配函数定义?

PS:{((?&gt;[^{}]+|(?R))*)} 匹配平衡括号

【问题讨论】:

    标签: python regex regex-lookarounds


    【解决方案1】:

    假设您正在使用 PyPi regex 模块,您可以使用

    import regex
    text = """void function{ {  {  } }}   
    static stTLookupTable RxTable[MAX]={
         
        {zero, one},{zero, one},{zero, one}};"""
    
    print( [x.group(3) for x in regex.finditer(r'=\s*({(?>[^{}]+|(?1))*})(*SKIP)(*F)|({((?>[^{}]+|(?2))*)})', text)] )
    # => [' {  {  } }']
    

    请参阅Python demo online

    详情

    • =\s*({(?&gt;[^{}]+|(?1))*})(*SKIP)(*F):
      • = - 一个 = 字符
      • \s* - 零个或多个空格
      • ({(?&gt;[^{}]+|(?1))*}) - 平衡 {...} 之间的子串
      • (*SKIP)(*F) - 跳过匹配并从失败位置重新开始搜索
    • | - 或
    • ({((?&gt;[^{}]+|(?2))*)}) - 第 2 组(技术,用于递归):
      • {((?&gt;[^{}]+|(?2))*)} - 匹配带有平衡花括号的 {...} 子字符串。

    您需要从比赛中返回第 3 组。

    【讨论】:

    • 这行得通,但我把它作为一个列表。我实际上想用“”(无)替换函数def中的整个{....}。我已经从一个文件中读取并将其存储到一个字符串中。所以,我希望能够做到这一点 - newstring = re.sub(pattern,")
    • @Aparnavenugopal regex.sub(r'=\s*({(?&gt;[^{}]+|(?1))*})(*SKIP)(*F)|({((?&gt;[^{}]+|(?2))*)})', r'{none}', text),见demo
    • 谢谢你,我的错。您已经在答案中提供了 req 信息。但是我不明白为什么它没有选择数组初始化。如果可能的话,你能解释一下吗?
    • @Aparnavenugopal 它没有选择RxTable[MAX]={...},因为={...} 文本已匹配并且跳过(*SKIP)(*F) - 跳过匹配并从以下位置重新开始搜索故障位置
    • @Wiktor Stribiżew谢谢你的解释
    【解决方案2】:

    使用(?R) 将递归整个模式。

    您可以匹配 void 函数 或除 [MAX]= 之外的任何内容,方法是匹配单词字符 \w+ 或使用 [^\s{}=,]+ 排除允许的字符并递归第一个子模式(?1) 使用 PyPi 正则表达式模块。

    \w+(?: \w+)*({(?:[^{}]++|(?1))*})
    

    说明

    • \w+(?: \w+)* 匹配 { 之前的 1 个或多个单词
    • ( 捕获第 1 组
      • {(?:[^{}]++|(?1))*} 匹配开闭卷曲的递归第一个子模式(?1)
    • )关闭第一组

    Regex demo | Python demo

    import regex
    
    pattern = r"\w+(?: \w+)*({(?:[^{}]++|(?1))*})"
    
    s = ("void function{ {  {  } }} \n\n\n"
        "static stTLookupTable RxTable[MAX]={\n"
        "     \n"
        "    {zero, one},{zero, one},{zero, one}};")
    
    matches = regex.finditer(pattern, s)
    
    for matchNum, match in enumerate(matches, start=1):    
        print (match.group())
    

    输出

    void function{ {  {  } }}
    

    删除{...} 部分:

    import regex
    
    pattern = r"(\w+(?: \w+))({(?:[^{}]++|(?2))*})"
    
    s = ("void function{ {  {  } }} \n\n\n"
        "static stTLookupTable RxTable[MAX]={\n"
        "     \n"
        "    {zero, one},{zero, one},{zero, one}};")
    
    print(regex.sub(pattern, r"\1", s))
    

    查看另一个python demo

    【讨论】:

      猜你喜欢
      • 2021-10-11
      • 1970-01-01
      • 1970-01-01
      • 2015-08-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多