在python中一一搜索替换

问题描述 投票:0回答:1

我尝试在 Markdown 表达式中寻找模式。这是我的代码:

import re
    
redmineToGitlabIdMap = dict()
redmineToGitlabIdMap[150767] = { 'iid': 1 }
redmineToGitlabIdMap[150768] = { 'iid': 2 }
redmineToGitlabIdMap[150769] = { 'iid': 3 }

description = '*(from redmine: issue id 150767, created on 2024-02-27 by **me**)*\n\n* Relations:\n  * copied_to #150767\n  * relates #150768\n  * relates #150769'
pattern = r'(\s*\* (?:relates|parent|child|copied_to)) #(\d+)'
    
for _, redmineId in re.findall(pattern, description):
  targetGitlabId = redmineToGitlabIdMap[int(redmineId)]['iid']
  description = re.sub(pattern, f'\\1 #{ targetGitlabId }', description, count=1)

print(description)
    

如您所见,我正在迭代正则表达式找到的匹配项,以便将它们一一替换为

redmineToGitlabIdMap
字典中各自的值。

但是,当我执行该操作时,它始终只会替换第一个出现的位置并返回此

* Relations:
  * copied_to #3
  * relates #150768
  * relates #150769

虽然应该打印:

* Relations:
  * copied_to #1
  * relates #2
  * relates #3
python regex
1个回答
0
投票

您的代码有几个问题。 首先,您似乎正在尝试创建一个嵌套字典,但不清楚原因。 为了简单起见,只需使用 int 值作为键,并使用计数器作为替换。 接下来,一次进行一个替换的规范方法是使用

re.sub()
和回调函数。 对于找到的每个匹配,在映射中查找整数值,然后构建替换。

将这些放在一起我们可以尝试:

import re

redmineToGitlabIdMap = {}
redmineToGitlabIdMap['150767'] = '1'
redmineToGitlabIdMap['150768'] = '2'
redmineToGitlabIdMap['150769'] = '3'

description = '*(from redmine: issue id 150767, created on 2024-02-27 by **me**)*\n\n* Relations:\n  * copied_to #150767\n  * relates #150768\n  * relates #150769'
pattern = r'\b(relates|parent|child|copied_to) #(\d+)'

def repl(m):
    description = m.group()
    if m.group(2) in redmineToGitlabIdMap.keys():
        targetGitlabId = redmineToGitlabIdMap[m.group(2)]
        description = m.group(1) + ' #' + targetGitlabId
        return description
    else:
        return description

description = re.sub(pattern, repl, description, flags=re.M|re.S)
print(description)

打印:

*(from redmine: issue id 150767, created on 2024-02-27 by **me**)*

* Relations:
  * copied_to #1
  * relates #2
  * relates #3
© www.soinside.com 2019 - 2024. All rights reserved.