字符串操作/正则表达式 - 查找和替换

Posted

技术标签:

【中文标题】字符串操作/正则表达式 - 查找和替换【英文标题】:string operation/regex - find and replace 【发布时间】:2020-12-22 15:29:49 【问题描述】:

我正在尝试替换下面txt文件中.之后的每个单词:

line1
line2
field: [orders.cancelled,orders.delivered,orders.reached
orders.pickup,orders.time]
some line
some line

我有一本字典:

   d = 'cancelled':'cancelled_at', 'deliver':'xxx'

我正在运行以下代码。但是,我得到了部分匹配的结果,即

我看到新文件有以下文字

field: [orders.cancelled_at, orders.xxxed ..........

从交付的单词来看,程序仍在替换前 7 个单词(交付)并在末尾添加“ed”。我不知道为什么

with open('list.txt', 'r') as g:
    text = g.read()
    for k in d:
        before = f'.k'
        after = f'.d[k]
        #print(before)
        #print(after)
        text = text.replace(before, after)
        #print(text)

with open('new_list.txt', 'w') as w:
    w.write(text)

我也试过这个,我得到了同样的结果

import re

with open('list.txt', 'r') as f:
    text = f.read()
    for k in d:
        before = f'.k(?!=\w)'
        print(before)
        after = f'.d[k]'
        print(after)
        text = re.sub(before, after, text)

with open('new_list.txt', 'w') as w:
    w.write(text)

【问题讨论】:

您正在用 xxx 替换 delivered 中的 deliver。结果是xxxed。将"delivered": "xxx" 添加到您的字典中。 1) 使用单词边界来匹配整个单词,2) 在字符类之外转义 . 以匹配文字 . @spyralab 如果键的值是“交付”而不是“交付”,我只想删除点后面的单词。如果找不到完全匹配,我希望程序不会更改任何内容,在这种情况下,它应该将新行作为 orders.cancelled_at, orders._delivered f'\bk\b' - 这应该有效吗? @WiktorStribiżew 抱歉,我对正则表达式不太熟悉,如果您能解释更多,将不胜感激 \b 单词边界只有在字符串中有整个单词时才需要匹配,因此short\b 将匹配short. 而不是shorts 【参考方案1】:

你可以使用

import re

d = 'cancelled':'cancelled_at', 'deliver':'xxx'
rx = re.compile(fr"(?<=\.)(?:'|'.join(d))\b")

with open('list.txt', 'r') as f:
    print( re.sub(rx, lambda x: d[x.group()], f.read()) )

见Python demo

代码生成的正则表达式看起来像

(?<=\.)(?:cancelled|deliver)\b

请参阅regex demo。详情:

(?&lt;=\.) - 一个正向的后视,它匹配紧接前面有文字 . 的位置 (?:cancelled|deliver) - 两种选择:cancelleddeliver \b - 作为整个单词,\b 是一个单词边界。

lambda x: d[x.group()] 替换将匹配的单词替换为对应的字典键值。

【讨论】:

嘿,你能解释一下我们什么时候使用 'f' 'fr' ,我可以看到你在 re.complie 中使用了 fr。如果您能解释它们之间的区别,将不胜感激 @HamzaShehzad r 是用于定义字符串文字的原始字符串文字前缀,其中反斜杠不用于形成字符串转义序列(请阅读Regular expression works on regex101.com, but not on prod 中的奖励顶部部分)线程。 f 是一个f-string 前缀,允许使用变量插值(或变量扩展),即在字符串文字中使用varname 将您手动添加的字符串与变量实际连接起来(而不是使用@ 987654339@)

以上是关于字符串操作/正则表达式 - 查找和替换的主要内容,如果未能解决你的问题,请参考以下文章

在多个文件中查找和替换正则表达式的最佳工具是啥?

#转#VS2012 正则表达式 动态插入 动态替换 (查找和替换工具)

正则表达式查找匹配后如何替换?

基础知识

java中怎么替换string中的某个字符

正则表达式语法