复杂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')
更复杂的是,这些额外的标准适用:
- 此列表可能会增长到数千项,
- 标记化可能达到 10 个左右的标记
- 标记化可以按任何顺序进行(因此 george 可以出现在开头、中间、结尾)
- 我们可能还想在 georgeH 和 brainW35 出现时捕获它们,只要它们以 george 或 brian 开始。
- 我们可能有 N 个要搜索的名字(即 george|brian|jim|al,但只有当它们是带有两个下划线的字符串时才会这样。
简化它们:
- 行永远不会以“_”开始或结束,并且应该只 begin/end 与 [a-zA-Z0-9]
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",
)
我正在寻求关于一个棘手的 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')
更复杂的是,这些额外的标准适用:
- 此列表可能会增长到数千项,
- 标记化可能达到 10 个左右的标记
- 标记化可以按任何顺序进行(因此 george 可以出现在开头、中间、结尾)
- 我们可能还想在 georgeH 和 brainW35 出现时捕获它们,只要它们以 george 或 brian 开始。
- 我们可能有 N 个要搜索的名字(即 george|brian|jim|al,但只有当它们是带有两个下划线的字符串时才会这样。
简化它们:
- 行永远不会以“_”开始或结束,并且应该只 begin/end 与 [a-zA-Z0-9]
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",
)