我正在尝试创建一个简单的脚本,它将从文件中获取正则表达式,然后在另一个文件上执行搜索和替换。这就是我所拥有但它不起作用,文件没有改变,我做错了什么?
import re, fileinput
separator = ' => '
file = open("searches.txt", "r")
for search in file:
pattern, replacement = search.split(separator)
pattern = 'r"""' + pattern + '"""'
replacement = 'r"""' + replacement + '"""'
for line in fileinput.input("test.txt", inplace=1):
line = re.sub(pattern, replacement, line)
print(line, end="")
文件 searches.txt 如下所示:
<p (class="test">.+?)</p> => <h1 \1</h1>
(<p class="not">).+?(</p>) => \1This was changed by the script\2
和 test.txt 是这样的:
<p class="test">This is an element with the test class</p>
<p class="not">This is an element without the test class</p>
<p class="test">This is another element with the test class</p>
我做了一个测试,看它是否正确地从文件中获取表达式:
>>> separator = ' => '
>>> file = open("searches.txt", "r")
>>> for search in file:
... pattern, replacement = search.split(separator)
... pattern = 'r"""' + pattern + '"""'
... replacement = 'r"""' + replacement + '"""'
... print(pattern)
... print(replacement)
...
r"""<p (class="test">.+?)</p>"""
r"""<h1 \1</h1>
"""
r"""(<p class="not">).+?(</p>)"""
r"""\1This was changed by the script\2"""
由于某种原因,第一个替换上的结束三重引号是换行符,这可能是我问题的原因吗?
答案 0 :(得分:3)
您不需要
pattern = 'r"""' + pattern + '"""'
在对re.sub的调用中,pattern
应该是实际的正则表达式。所以<p (class="test">.+?)</p>
。当你在它周围包装所有这些双引号时,它会使模式永远不会与文件中的文本匹配。
即使您似乎看到过这样的代码:
replaced = re.sub(r"""\w+""", '-')
在这种情况下,r"""
向python解释器指示您正在讨论“原始”多行字符串,或者不应该替换反斜杠序列的字符串(例如\ n替换为换行符) 。程序员经常在python中使用“原始”字符串来引用正则表达式,因为他们想要使用正则表达式序列(如上面的\w
)而不必引用反斜杠。如果没有原始字符串,正则表达式必须是'\\w+'
,这会让人感到困惑。
但无论如何,您根本不需要三重双引号。最后一个代码短语可以写成:
replaced = re.sub(r'\w+', '-')
最后,你的另一个问题是输入文件中有换行符,将pattern =&gt;的每个案例分开。替换。所以它真的是“pattern =&gt; replacement \ n”,并且尾随换行符跟随你的替换变量。尝试做:
for search in file:
search = search.rstrip() #Remove the trailing \n from the input
pattern, replacement = search.split(separator)
答案 1 :(得分:1)
两个观察结果:
1)在阅读文件时使用.strip()
,如下所示:
pattern, replacement = search.strip().split(separator)
这将从文件中删除\n
2)如果您打算从模式中转义正则表达式元字符,请使用re.escape()而不是r“”“+ str +”“”形式