复杂QSortFilterProxyModel.setFilterRegex。是否可以在一场比赛中进行比赛?

Complicated QSortFilterProxyModel.setFilterRegex. Is it possible to match within a match?

我正在寻求关于一个棘手的 QRegExp 的帮助,我想将其传递给我的 QSortFilterProxyModel.setFilterRegex。我一直在努力寻找能够处理我的用例的解决方案。

从下面的示例代码中,我需要捕获带有 两个下划线 (_) 的项目,但是 ONLY 如果它们有 george 布赖恩。我不想要多于或少于两个下划线的项目。

string_list = [
'john','paul','george','ringo','brian','carl','al','mike',
'john_paul','paul_george','john_ringo','george_ringo',
'john_paul_george','john_paul_brian','john_paul_ringo',
'john_paul_carl','paul_mike_brian','john_george_brian',
'george_ringo_brian','paul_george_ringo','john_george_ringo',
'john_paul_george_ringo','john_paul_george_ringo_brian','john_paul_george_ringo_brian_carl',
]

view = QListView()
model = QStringListModel(string_list)
proxy_model = QSortFilterProxyModel()
proxy_model.setSourceModel(model)
view.setModel(proxy_model)
view.show()

第一部分(匹配两个下划线)可以用行来完成(这里简化了,但实际上每个标记都可以由 任何 字母数字字符组成,而不是 _,所以 [ a-zA-Z0-9]*):

proxy_model.setFilterRegExp('^[a-z]*_[a-z]*_[a-z]*$')

第二部分可以完成(独立完成)

proxy_model.setFilterRegExp('george|brian')

更复杂的是,这些额外的标准适用:

简化它们:

QRegExp 和 QSortFilterProxyModel 是否具有我正在寻找的功能,或者我是否需要求助于其他方法?

对于非常复杂的条件,使用正则表达式不是很有用,在这种情况下,最好覆盖 filterAcceptsRow 方法,您可以在其中实现过滤器功能,如以下简单示例所示:

class FilterProxyModel(QSortFilterProxyModel):
    _words = None
    _number_of_underscore = -1

    def filterAcceptsRow(self, source_row, source_parent):
        text = self.sourceModel().index(source_row, 0, source_parent).data()
        if not self._words or self._number_of_underscore < 0:
            return True
        return (
            any([word in text for word in self._words])
            and text.count("_") == self._number_of_underscore
        )

    @property
    def words(self):
        return self._words

    @words.setter
    def words(self, words):
        self._words = words
        self.invalidateFilter()

    @property
    def number_of_underscore(self):
        return self._number_of_underscore

    @number_of_underscore.setter
    def number_of_underscore(self, number):
        self._number_of_underscore = number
        self.invalidateFilter()
view = QListView()
model = QStringListModel(string_list)
proxy_model = FilterProxyModel()
proxy_model.setSourceModel(model)
view.setModel(proxy_model)
view.show()

proxy_model.number_of_underscore = 2
proxy_model.words = (
    "george",
    "brian",
)