Search code examples
pythonregexqtqregexpqsortfilterproxymodel

QRegExp For QSortFilterProxyModel - Find All Items In A List


Am using PyQt & getting stuck on using setFilterRegExp() with a QSortFilterProxyModel. The source model outputs integers 1-30, and the QSFPM is to filter 1-30, leaving only the numbers in a supplied list.

proxy.setFilterRegExp(QRegExp('^%s{1,1}%' % sourceModel.wantedNumbersList()))

If manually entering the desired numbers:

proxy.setFilterRegExp(QRegExp('^[2, 3, 4, 5, 8, 9, 10, 18, 19]{1,1}%'))

both result in [1, 2, 3, 4, 5, 8, 9] being left. The desired numbers >=10 aren't left in the results, and 1 is included for some reason.

Also tried:

proxy.setFilterRegExp(RegExp('^[2|3|4|15]{1,1}$')))

..which gave [1,2,3,4,5] i.e. interpreted the desired number 15 as 1 & 5.

From the docs, I thought ^ & $ would find exact matches of each, but instead finds all occurrences of all numbers.

Many Regards


Solution

  • The thing is that character classes treat characters inside them as individual characters, unless when using a range. So, what:

    [2, 3, 4, 5, 8, 9, 10, 18, 19]
    

    Will match is: 2, ,, , 3, , (again), [...], 1, 9, , (again), , 1 (again), etc.

    What the regex has to look like is actually:

    proxy.setFilterRegExp(QRegExp('^(2|3|4|5|8|9|10|18|19)$'))
    

    Or shortened as much as possible:

    proxy.setFilterRegExp(QRegExp('^([234589]|1[089])$'))
    

    I guess you will have to change how sourceModel.wantedNumbersList() appears (some string manipulations) or input it manually.

    If you do it via string manipulation, I would suggest stripping the square brackets and replace the comma followed by space by a pipe |, then use '^(%s)$' for regex.