Python pandoc降价引用的正则表达式

Python pandoc降价引用的正则表达式,python,regex,regex-group,Python,Regex,Regex Group,我正试图搜索并替换pandoc markdown的引用。 它们具有以下语法: [prenote @autorkey, postnote] 或者对于不止一个作者 [prenote1 @authorekey1, postnote1; prenote2 @authorkey2, postnote2] pre notes、author Key和post notes应分别位于各自的捕获组中 对于引文中的一位作者,我使用了正则表达式: \[(.*)?@(.*)(,(.*))?\] 但我不知道如何将引用

我正试图搜索并替换pandoc markdown的引用。 它们具有以下语法:

[prenote @autorkey, postnote]
或者对于不止一个作者

[prenote1 @authorekey1, postnote1; prenote2 @authorkey2, postnote2]
pre notes、author Key和post notes应分别位于各自的捕获组中

对于引文中的一位作者,我使用了正则表达式:

\[(.*)?@(.*)(,(.*))?\]
但我不知道如何将引用与多个作者进行匹配。 理想情况下,可以将引用与一个或多个作者关键字进行匹配。 前注和后注应该是可选的


这可能吗?

我们需要更多的上下文和代码(完整的示例代码)才能完整地回答,因此我只能用与您提问相同的一般方式来回答

我不相信你能用一个正则表达式在一次操作中完成它

因此,我将使用的总体技术是:

  • 首先,使用一个简单的正则表达式将整个引用(与一个或多个作者)与一个组进行匹配,即对
    [
    ]
    之间的所有内容进行匹配
  • 然后,当找到匹配项时,将该匹配项中的内容(即方括号中的所有内容)拆分为
    获取
    “prenote@authorkey,postnote”
    字符串列表
  • 对生成的单个作者字符串列表中的每个元素执行所需的替换
  • 通过再次用分号连接结果列表并在其周围添加
    [
    ]
    将最终引用缝合在一起
  • 将最后的引用放在原文中,而不是匹配的字符串中
  • 您可以将步骤2到4放入函数
    f(匹配对象)
    ,然后使用进行替换。它将为找到的每个匹配调用函数
    f
    ,并将该匹配替换为返回值
    f

    ,您可以使用来获取3个捕获组

    (?:\G(?!^)|\[(?=[^][\r\n]*\]))[^\S\r\n]*(.*?) @(.*?), ([^][,\r\n]*)[\];]
    
    |

    解释

    • (?:
      非捕获组
      • \G(?!^)
        在上一个匹配的末尾而不是开始处断言位置
      • |
      • \[(?=[^][\r\n]*\])
        匹配
        [
        并断言存在结束
        ]
    • 关闭非捕获组
    • [^\S\r\n]*
      匹配除换行符以外的0+个空格字符
    • (.*)
      捕获组1,尽可能匹配除换行符以外的任何字符
    • @
      逐字匹配
    • (.*)
      捕获组2,尽可能匹配除换行符以外的任何字符
    • 逐字匹配
    • ([^][,\r\n]*)
      捕获组3,匹配除
      ]以外的任何字符
      [
      或换行符
    • [\];]
      匹配
      ]
    使用regex.finditer的示例代码

    import regex
    
    pattern = r"(?:\G(?!^)|\[(?=[^][\r\n]*\]))[^\S\r\n]*(.*?) @(.*?), ([^][,\r\n]*)[\];]"
    
    test_str = ("[prenote @autorkey, postnote]\n"
                "[prenote1 @authorekey1, postnote1; prenote2 @authorkey2, postnote2]\n")
    
    matches = regex.finditer(pattern, test_str)
    
    for matchNum, match in enumerate(matches, start=1):
        for groupNum in range(0, len(match.groups())):
            groupNum = groupNum + 1
    
            print (match.group(groupNum))
    
    输出

    prenote
    autorkey
    postnote
    prenote1
    authorekey1
    postnote1
    prenote2
    authorkey2
    postnote2
    
    “预注释、作者键和后注释应分别位于各自的捕获组中”。您试图做的是捕获动态数量的捕获组,即重复一个捕获组。它不会以这种方式工作(来源:链接到的链接)。