先解释一下问题的由来
查找和替换是文本编辑的基本功能
查找很简单,因为有现成的find()函数
但是对于替换,如果只要单次替换一个字符串
textEdit = QTextEdit()
text = textEdit.toPlainText()
text.find(oldString)
cursor = text.textCursor()
cursor.insertText(newString)
简单的几句就可以完成,因为find()本身除了查找以外,也隐含了对游标的位置移动(movePosition),以及对查找的字符串的选择(keepAnchor)
除此以外还有两个我特别关注的点:
- find()支持QTextEdit内置的方法undo(),就是说支持撤销操作
- find()的效率足够高,几十MB的文本文件也没有太大压力
现在我想实现更高级的功能:全部替换,而且也能胜任上述两个需求
这个时候问题来了
如果只要实现全部替换的功能倒是有很取巧的操作
textEdit.setPlainText(text.replace(oldString, newString))
可是一旦这么做以后,undo()的功能就失效了,虽然不清楚底层原理,但也可以大致猜想应该是一旦setPlaintText,undo()会被重置;
还有一种方法就是重复调用单次替换的操作,看起来很美好,但是效能惨不忍睹,想想看每次替换后都需要重新获取文本内容,重新定位字符串的位置,一旦文本内容变大,计算的复杂度大概会呈指数级增长(猜的),实测结果根本扛不住
所以我的问题是 有没有更好的方法来实现全局替换?而且能满足上述两个需求?
似乎QTextEdit 可以多重选择,也许有一个正统的方法,但我不知道怎么做