循环正则表达式替换python中的字符串 - 缺少明显的

时间:2015-06-06 21:14:46

标签: python regex

我试图通过文档中的引用来迭代删除第2,第3 ......第n位作者,其中引用的形式(在一些清理步骤之后)

  

Straat,Ark,Sijtsma 2013,75-99。

     

Nardulli,Peyton,Bajjalieh 2013,139-192。

我的策略是,引用表格AUTHOR1 ... AUTHORn-1 AUTHORn YEAR:

1)匹配AUTHORn-1 AUTHORn YEAR,

2)使用组替换,将匹配的子字符串替换为AUTHORn-1 YEAR,以便整体引用变为AUTHOR1 ... AUTHORn-1 YEAR。

3)然后循环再做一遍,直到剩下的都是AUTHOR1 YEAR。我在这里进行了十次迭代,因为我知道没有超过十人的多作者引用。

我的代码如下:

def multiAuthor(citestring):
    longcite = r'([\s(][A-Z1][A-Za-z1]*-?[A-Za-z1]*),[\s(][A-Z1][A-Za-z1]*-?[A-Za-z1]*[ ,]?( \(?\d\d\d\d[a-z]?[\s.,)])'
    for x in range(0, 10):
        newstring = re.sub(longcite, '\g<1>\g<2>', citestring)
    return(newstring)

这是在由换行符分隔的一串脚注上调用的,它适用于第一次迭代。对于上面给出的两个示例匹配,它会正确返回:

  

Straat,Ark 2013,75-99。

     

Nardulli,Peyton 2013,139-192。

但是那就是它。它不能在第一个循环之外的任何循环上成功执行替换,因此无法剥离第二个作者。

我一直在使用regex101进行调试,但我正式感到难过。表达式的第一次迭代:https://www.regex101.com/r/jM2fF4/3 ---然后在运行替换后,第二个循环上的正则表达式也匹配,并且应该再次替换:https://regex101.com/r/fZ1pX7/4

所以我觉得我的正则表达式是正确的。我只是遗漏了一些愚蠢而明显的东西吗? (我对python-land很新,但是我已经对我的循环语法进行了双重和三重检查,我认为这是正确的。)

使用python 3。

如果你想为自己看到它的实际效果,我还在这里放了一个最小的可运行的例子(用空格代替换行,但没有差异):https://github.com/paultopia/stray-cites/blob/master/minimal-test.py

拯救我,StackObi Wan,你是我唯一的希望......?

编辑:我确实错过了一些明显的东西,请看下面我的自我回答;把它留下来因为它可能是一个常见的oopsie。

2 个答案:

答案 0 :(得分:1)

这是你想要的吗?

([^,]*).*?([0-9].*?)\.\s*

查看regex101上的分叉。

  • ([^,]*)最多匹配,(逗号)
  • .*?忽略了很久......
  • ([0-9].*?)\. matches a digit up to。`(dot)
  • \s*匹配此
  • 之后的任何空格

然后,在替换中:

`\1 \2`

这是上面的第一个和第二个匹配 - 分别是名称和页码/年。

答案 1 :(得分:0)

我是个白痴。每次我在stackoverflow上发帖,我都会关掉电脑然后走开,五分钟后,答案就出现了。

循环不起作用,因为在每次迭代时,它都会在原始字符串上找到匹配,而不是在前一个循环操作的字符串上找到匹配。正确的代码:

def multiAuthor(citestring):
    longcite = r'([\s(][A-Z1][A-Za-z1]*-?[A-Za-z1]*),[\s(][A-Z1][A-Za-z1]*-?[A-Za-z1]*[ ,]?( \(?\d\d\d\d[a-z]?[\s.,)])'
    for x in range(0, 10):
        citestring = re.sub(longcite, '\g<1>\g<2>', citestring)
    return(citestring)