def testMatchIterator(self): re = QRegularExpression('(\w+)') self.assertTrue(re.isValid()) count = 0 it = re.globalMatch('word1 word2 word3') while it.hasNext(): it.next() count = count + 1 self.assertEqual(count, 3)
def __init__(self, parent=None): QSortFilterProxyModel.__init__(self, parent) # char* m_filterRoles; self.m_filterRoles = "" # char* m_sortData; self.m_sortData = "" self.m_typeSort = 0 self.m_boolSignalReset = False self.m_reguexp = QRegularExpression() self.m_strexp = "" self.m_boolstrexp = True self.m_boolVacio = True
def highlightBlock(self, text): myClassFormat = QTextCharFormat() myClassFormat.setFontWeight(QFont.Bold) expression = QRegularExpression(self.pattern) i = expression.globalMatch(text) while i.hasNext(): match = i.next() myClassFormat.setForeground( self.tagColorMap[match.capturedTexts()[0]]) self.setFormat(match.capturedStart(), match.capturedLength(), myClassFormat)
def __init__(self, document): QSyntaxHighlighter.__init__(self, document) # Multi-line strings (expression, flag, style) FIXME: The triple-quotes # in these two lines will mess up the syntax highlighting from this # point onward self.tri_single = (QRegularExpression("'''"), 1, self.styles['string2']) self.tri_double = (QRegularExpression('"""'), 2, self.styles['string2']) rules = [] # Keyword, operator, and brace rules rules += [(r'\b%s\b' % w, 0, self.styles['keyword']) for w in PythonHighlighter.keywords_bold] rules += [(r'\b%s\b' % w, 0, self.styles['keyword2']) for w in PythonHighlighter.keywords] rules += [(r'\b%s\b' % o, 0, self.styles['operator']) for o in PythonHighlighter.operators] rules += [(r'\b%s\b' % b, 0, self.styles['brace']) for b in PythonHighlighter.braces] # All other rules rules += [ # 'def' followed by an identifier (r'\bdef\b\s*(\w+)', 1, self.styles['def']), # 'class' followed by an identifier (r'\bclass\b\s*(\w+)', 1, self.styles['class']), # Numeric literals (r'\b[+-]?[0-9]+[lL]?\b', 0, self.styles['numbers']), (r'\b[+-]?0[xX][0-9A-Fa-f]+[lL]?\b', 0, self.styles['numbers']), (r'\b[+-]?[0-9]+(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?\b', 0, self.styles['numbers']), # From '#' until a newline (r"""#[^\n'{2}"{2}]*""", 0, self.styles['comment']), # Double and Single-quoted string, possibly containing escape sequences (r'"[^"\\]*(\\.[^"\\]*)*"', 0, self.styles['string']), (r"'[^'\\]*(\\.[^'\\]*)*'", 0, self.styles['string']), # Complete line commented (r'^[\s]*(#[^\n]*)', 1, self.styles['comment']), # Decorators (r'^[\s]*(@[^(]*)', 1, self.styles['decorator']), ] # Build a QRegularExpression for each pattern self.rules = [(QRegularExpression(pat), index, fmt) for (pat, index, fmt) in rules]
def replace_command(self, index: QModelIndex, undo_parent: QUndoCommand = None): search_txt = self.edit_search.text() replace_txt = self.edit_replace.text() item_text = index.data(role=Qt.DisplayRole) if self.check_case.isChecked(): flags = 0 else: flags = re.IGNORECASE try: new_text = re.sub(QRegularExpression.escape(search_txt), replace_txt, item_text, flags=flags) except Exception as e: LOGGER.error(e) return if new_text == item_text: return return ItemEditUndoCommand(item_text, new_text, index, undo_parent, editing_done=False)
def update_rules(self): self.rules = [] self.rules += [(r'\b%s\b' % w, 0, self.styles['keyword']) for w in keywords] self.rules += [(r'%s' % o, 0, self.styles['operator']) for o in operators] self.rules += [(r'%s' % b, 0, self.styles['brace']) for b in braces] self.rules += [ (r'\bself\b', 0, self.styles['self']), (r'"[^"\\]*(\\.[^"\\]*)*"', 0, self.styles['string']), (r"'[^'\\]*(\\.[^'\\]*)*'", 0, self.styles['string']), (r'\bdef\b\s*(\w+)', 1, self.styles['defclass']), # 'class' followed by an identifier (r'\bclass\b\s*(\w+)', 1, self.styles['defclass']), (r'#[^\n]*', 0, self.styles['comment']), (r'\b[+-]?[0-9]+[lL]?\b', 0, self.styles['numbers']), (r'\b[+-]?0[xX][0-9A-Fa-f]+[lL]?\b', 0, self.styles['numbers']), (r'\b[+-]?[0-9]+(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?\b', 0, self.styles['numbers']), ] self.rules = [(QRegularExpression(pat), index, fmt) for (pat, index, fmt) in self.rules] self.tri_single = (QRegExp("'''"), 1, self.styles['string2']) self.tri_double = (QRegExp('"""'), 2, self.styles['string2'])
def __init__(self, document): """""" QSyntaxHighlighter.__init__(self, document) rules = [] # Keyword, operator, and brace rules rules += [(r'\b%s\b' % w, 0, self.styles['keyword']) for w in CSSHighlighter.keywords] rules += [(r'( )', 0, format('#4f5b62'))] # All other rules rules += [(r'"[^"\\]*(\\.[^"\\]*)*"', 0, self.styles['value']), (r"'[^'\\]*(\\.[^'\\]*)*'", 0, self.styles['value']), (r'^([\w]+)[#\.\w\[\]=]*\s*\{', 1, self.styles['selector']), (r'^\s*([\w-]+)\s*:\s*([\w\'"#]+)', 1, self.styles['key']), (r'^\s*([\w-]+)\s*:\s*([\w\'"#]+)', 2, self.styles['value']), # Numeric literals (r'\b[+-]?[0-9]+[lL]?\b', 0, self.styles['numbers']), (r'\b[+-]?0[xX][0-9A-Fa-f]+[lL]?\b', 0, self.styles['numbers']), (r'\b[+-]?[0-9]+(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?\b', 0, self.styles['numbers']), ] # Build a QRegularExpression for each pattern self.rules = [(QRegularExpression(pat), index, fmt) for (pat, index, fmt) in rules]
def reNumaelis(self, text): if text == "": return text lista = text.split(QRegularExpression("\\s+")) tem2 = "" for item in lista: tem2 += "(?=.*" + item.strip() + ")" return tem2
def setFilterRegularExpression(self) -> None: """ Custom slot to set case insensitivity """ if not self.__model: return exp = QRegularExpression( self.__searchKeyword, options=QRegularExpression.CaseInsensitiveOption) self.__model.setFilterRegularExpression(exp)
def search(self, pattern, row, col, direction): nocase = not self.case_button.isChecked() word = self.word_button.isChecked() regex = self.regex_button.isChecked() matches = 0 index = 0 if direction > 0: row_range = range(self.table_widget.rowCount() - 1, -1, -1) col_range = range(self.table_widget.columnCount() - 1, -1, -1) else: row_range = range(self.table_widget.rowCount()) col_range = range(self.table_widget.columnCount()) for i in row_range: for j in col_range: item = self.table_widget.item(i, j) if item is not None: text = item.text() if regex: match = QRegularExpression(pattern).match( text).hasMatch() else: if nocase: text = text.lower() pattern = pattern.lower() if word: match = text == pattern else: match = pattern in text if match and pattern: self.table_widget.item(i, j).setBackground(Qt.yellow) if (direction > 0 and (i > row or i == row and j > col)) or ( direction < 0 and (i < row or i == row and j < col)): self.table_widget.setCurrentCell(i, j) index = matches matches += 1 else: self.table_widget.item(i, j).setBackground(Qt.transparent) if pattern: self.matches_label.setVisible(True) if matches > 0: match = matches - index if direction > 0 else index + 1 self.matches_label.setText( self.tr(f"match #{match}/{matches}")) self.matches_label.setStyleSheet("color: #000000") modify_font(self.matches_label, bold=True) else: self.matches_label.setText(self.tr("not found!")) self.matches_label.setStyleSheet("color: #FF0000") modify_font(self.matches_label, italic=True) else: self.matches_label.setText("")
def set_completion_prefix(self, prefix: str): """Set prefix and filter model Args: prefix (str): A prefix keyword used to filter model """ self.view.clearSelection() self._completion_prefix = prefix self.proxy_model.setFilterRegularExpression( QRegularExpression(f"^{prefix}.*", QRegularExpression.CaseInsensitiveOption)) if self.proxy_model.rowCount() > 0: self.select_row(0)
def setupTabs(self): """ Setup the various tabs in the AddressWidget. """ groups = ["ABC", "DEF", "GHI", "JKL", "MNO", "PQR", "STU", "VW", "XYZ"] for group in groups: proxyModel = QSortFilterProxyModel(self) proxyModel.setSourceModel(self.tableModel) proxyModel.setDynamicSortFilter(True) tableView = QTableView() tableView.setModel(proxyModel) tableView.setSortingEnabled(True) tableView.setSelectionBehavior(QAbstractItemView.SelectRows) tableView.horizontalHeader().setStretchLastSection(True) tableView.verticalHeader().hide() tableView.setEditTriggers(QAbstractItemView.NoEditTriggers) tableView.setSelectionMode(QAbstractItemView.SingleSelection) # This here be the magic: we use the group name (e.g. "ABC") to # build the regex for the QSortFilterProxyModel for the group's # tab. The regex will end up looking like "^[ABC].*", only # allowing this tab to display items where the name starts with # "A", "B", or "C". Notice that we set it to be case-insensitive. re = QRegularExpression("^[{}].*".format(group)) assert re.isValid() re.setPatternOptions(QRegularExpression.CaseInsensitiveOption) proxyModel.setFilterRegularExpression(re) proxyModel.setFilterKeyColumn(0) # Filter on the "name" column proxyModel.sort(0, Qt.AscendingOrder) # This prevents an application crash (see: http://www.qtcentre.org/threads/58874-QListView-SelectionModel-selectionChanged-Crash) viewselectionmodel = tableView.selectionModel() tableView.selectionModel().selectionChanged.connect( self.selectionChanged) self.addTab(tableView, group)
def filterRegExpChanged(self): syntax_nr = self.filterSyntaxComboBox.currentData() pattern = self.filterPatternLineEdit.text() if syntax_nr == WILDCARD: pattern = QRegularExpression.wildcardToRegularExpression(pattern) elif syntax_nr == FIXED_STRING: pattern = QRegularExpression.escape(pattern) regExp = QRegularExpression(pattern) if not self.filterCaseSensitivityCheckBox.isChecked(): options = regExp.patternOptions() options |= QRegularExpression.CaseInsensitiveOption regExp.setPatternOptions(options) self.proxyModel.setFilterRegularExpression(regExp)
def apply_filter(self, text=None): """filter table to only show tests matching text""" if text is None: text = self.filter.text() if text: text = text.replace("(", "\(") text = text.replace(")", "\)") m = QRegularExpression(text) m.setPatternOptions(QRegularExpression.CaseInsensitiveOption) if m.isValid(): m.optimize() filter = lambda row_num: m.match( self.table.item(row_num, 0).text()).hasMatch() else: return else: filter = lambda row: True for i in range(0, self.table.rowCount()): self.table.setRowHidden(i, not filter(i))
def setFilter(self, search: str) -> None: self.filtermodel.setFilterRegularExpression( QRegularExpression(search, QRegularExpression.CaseInsensitiveOption) )
def __init__(self, document=None): super().__init__(document) palette = QApplication.instance().palette("QTextEdit") # SQL Syntax highlighter rules # dict: pattern, font, color, minimal (not greedy) # TODO : What about dark mode ? self.highlighting_patterns = [ { # Keywords # \b allows to perform a "whole words only" "pattern": "|".join(("\\b%s\\b" % keyword for keyword in VqlSyntaxHighlighter.sql_keywords)), "font": QFont.Bold, "color": palette.color(QPalette.Highlight), # default: Qt.darkBlue "case_insensitive": True, }, { # Strings simple quotes '...' "pattern": r"\'.*\'", "color": Qt.red, "minimal": True, # Need to stop match as soon as possible }, { # Strings double quotes: "..." "pattern": r"\".*\"", "color": Qt.red, "minimal": True, # Need to stop match as soon as possible }, { # Numbers "pattern": r"\\b[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?\\b", "color": Qt.darkGreen, }, { # Comments "pattern": r"--[^\n]*", "color": Qt.gray, }, ] self.highlighting_rules = list() for pattern in self.highlighting_patterns: t_format = QTextCharFormat() font = pattern.get("font", None) if font: t_format.setFontWeight(font) color = pattern.get("color", None) if color: t_format.setForeground(color) regex = QRegularExpression(pattern["pattern"]) if pattern.get("minimal", False): # The greediness of the quantifiers is inverted: *, +, ?, {m,n}, etc. # become lazy, while their lazy versions (*?, +?, ??, {m,n}?, etc.) # become greedy. # https://doc.qt.io/Qt-5/qregularexpression.html#setPatternOptions regex.setPatternOptions( QRegularExpression.InvertedGreedinessOption) if pattern.get("case_insensitive", False): # NOTE: Deletes previous pattern options # Not serious in practice, this only concerns the keywords regex.setPatternOptions( QRegularExpression.CaseInsensitiveOption) self.highlighting_rules.append((regex, t_format))
def validateRegex(pattern, lineEdit): regex = QRegularExpression(pattern) if regex.isValid(): lineEdit.setStyleSheet("background-color: white;") else: lineEdit.setStyleSheet("background-color: red;")
class TypeChecker: def __init__(self, parent=None): self.bool_exp = QRegularExpression('^(true)|(false)$') assert self.bool_exp.isValid() self.bool_exp.setPatternOptions(QRegularExpression.CaseInsensitiveOption) self.byteArray_exp = QRegularExpression(r'^[\x00-\xff]*$') assert self.byteArray_exp.isValid() self.char_exp = QRegularExpression('^.$') assert self.char_exp.isValid() pattern = r'^[+-]?\d+$' self.int_exp = QRegularExpression(pattern) assert self.int_exp.isValid() pattern = r'^\(([0-9]*),([0-9]*),([0-9]*),([0-9]*)\)$' self.color_exp = QRegularExpression(pattern) assert self.color_exp.isValid() pattern = r'^\((-?[0-9]*),(-?[0-9]*)\)$' self.point_exp = QRegularExpression(pattern) assert self.point_exp.isValid() pattern = r'^\((-?[0-9]*),(-?[0-9]*),(-?[0-9]*),(-?[0-9]*)\)$' self.rect_exp = QRegularExpression(pattern) assert self.rect_exp.isValid() self.size_exp = QRegularExpression(self.point_exp) date_pattern = '([0-9]{,4})-([0-9]{,2})-([0-9]{,2})' self.date_exp = QRegularExpression('^{}$'.format(date_pattern)) assert self.date_exp.isValid() time_pattern = '([0-9]{,2}):([0-9]{,2}):([0-9]{,2})' self.time_exp = QRegularExpression('^{}$'.format(time_pattern)) assert self.time_exp.isValid() pattern = '^{}T{}$'.format(date_pattern, time_pattern) self.dateTime_exp = QRegularExpression(pattern) assert self.dateTime_exp.isValid() def type_from_text(self, text): if self.bool_exp.match(text).hasMatch(): return bool if self.int_exp.match(text).hasMatch(): return int return None def create_validator(self, value, parent): if isinstance(value, bool): return QRegularExpressionValidator(self.bool_exp, parent) if isinstance(value, float): return QDoubleValidator(parent) if isinstance(value, int): return QIntValidator(parent) if isinstance(value, QByteArray): return QRegularExpressionValidator(self.byteArray_exp, parent) if isinstance(value, QColor): return QRegularExpressionValidator(self.color_exp, parent) if isinstance(value, QDate): return QRegularExpressionValidator(self.date_exp, parent) if isinstance(value, QDateTime): return QRegularExpressionValidator(self.dateTime_exp, parent) if isinstance(value, QTime): return QRegularExpressionValidator(self.time_exp, parent) if isinstance(value, QPoint): return QRegularExpressionValidator(self.point_exp, parent) if isinstance(value, QRect): return QRegularExpressionValidator(self.rect_exp, parent) if isinstance(value, QSize): return QRegularExpressionValidator(self.size_exp, parent) return None def from_string(self, text, original_value): if isinstance(original_value, QColor): match = self.color_exp.match(text) return QColor(min(int(match.captured(1)), 255), min(int(match.captured(2)), 255), min(int(match.captured(3)), 255), min(int(match.captured(4)), 255)) if isinstance(original_value, QDate): value = QDate.fromString(text, Qt.ISODate) return value if value.isValid() else None if isinstance(original_value, QDateTime): value = QDateTime.fromString(text, Qt.ISODate) return value if value.isValid() else None if isinstance(original_value, QTime): value = QTime.fromString(text, Qt.ISODate) return value if value.isValid() else None if isinstance(original_value, QPoint): match = self.point_exp.match(text) return QPoint(int(match.captured(1)), int(match.captured(2))) if isinstance(original_value, QRect): match = self.rect_exp.match(text) return QRect(int(match.captured(1)), int(match.captured(2)), int(match.captured(3)), int(match.captured(4))) if isinstance(original_value, QSize): match = self.size_exp.match(text) return QSize(int(match.captured(1)), int(match.captured(2))) if isinstance(original_value, list): return text.split(',') return type(original_value)(text)
def testMatch(self): re = QRegularExpression('^.*(word2).*$') self.assertTrue(re.isValid()) match = re.match('word1 word2 word3') self.assertTrue(match.isValid()) self.assertEqual(match.captured(1), 'word2')
def __init__(self, parent=None): self.bool_exp = QRegularExpression('^(true)|(false)$') assert self.bool_exp.isValid() self.bool_exp.setPatternOptions(QRegularExpression.CaseInsensitiveOption) self.byteArray_exp = QRegularExpression(r'^[\x00-\xff]*$') assert self.byteArray_exp.isValid() self.char_exp = QRegularExpression('^.$') assert self.char_exp.isValid() pattern = r'^[+-]?\d+$' self.int_exp = QRegularExpression(pattern) assert self.int_exp.isValid() pattern = r'^\(([0-9]*),([0-9]*),([0-9]*),([0-9]*)\)$' self.color_exp = QRegularExpression(pattern) assert self.color_exp.isValid() pattern = r'^\((-?[0-9]*),(-?[0-9]*)\)$' self.point_exp = QRegularExpression(pattern) assert self.point_exp.isValid() pattern = r'^\((-?[0-9]*),(-?[0-9]*),(-?[0-9]*),(-?[0-9]*)\)$' self.rect_exp = QRegularExpression(pattern) assert self.rect_exp.isValid() self.size_exp = QRegularExpression(self.point_exp) date_pattern = '([0-9]{,4})-([0-9]{,2})-([0-9]{,2})' self.date_exp = QRegularExpression('^{}$'.format(date_pattern)) assert self.date_exp.isValid() time_pattern = '([0-9]{,2}):([0-9]{,2}):([0-9]{,2})' self.time_exp = QRegularExpression('^{}$'.format(time_pattern)) assert self.time_exp.isValid() pattern = '^{}T{}$'.format(date_pattern, time_pattern) self.dateTime_exp = QRegularExpression(pattern) assert self.dateTime_exp.isValid()
def filter_same_title(self): dup = self.proxy_model.sourceModel().pickup_same_title() re = QRegularExpression('|'.join(dup)) self.proxy_model.setFilterRegularExpression(re) self.filtering.emit(' - filtered')
class ProxyModelJson(QSortFilterProxyModel): def __init__(self, parent=None): QSortFilterProxyModel.__init__(self, parent) # char* m_filterRoles; self.m_filterRoles = "" # char* m_sortData; self.m_sortData = "" self.m_typeSort = 0 self.m_boolSignalReset = False self.m_reguexp = QRegularExpression() self.m_strexp = "" self.m_boolstrexp = True self.m_boolVacio = True def setFilterRoles(self, filterRoles): if self.m_filterRoles == filterRoles: return self.m_filterRoles = filterRoles # self.filterChanged() def setSortData(self, sortData): pass def setTypeSort(self, typeSort): if self.m_typeSort == typeSort: return self.m_typeSort = typeSort self.sortOrder() def reNumaelis(self, text): if text == "": return text lista = text.split(QRegularExpression("\\s+")) tem2 = "" for item in lista: tem2 += "(?=.*" + item.strip() + ")" return tem2 @Slot(bool) def setAscendingOrder(self, bao): if self.sortOrder() == Qt.AscendingOrder and bao == False: self.sort(0, Qt.DescendingOrder) if self.sortOrder() == Qt.DescendingOrder and bao == True: self.sort(0, Qt.AscendingOrder) @Slot(bool) def setEmitSignalReset(self, bes): # if(m_boolSignalReset!=bes){ # m_boolSignalReset=bes; # } pass def lessThan(self, left, right): rolis = self.sortRole() l = left.model().data(left, rolis) if left.model() == True else None r = right.model().data(right, rolis) if right.model() == True else None if l.__class__() == None: return None #return (r.type() != QVariant::Invalid); #if l.__class__() == '': # if self.isSortLocaleAware(): return (l.property(self.m_sortData) < (r.property(self.m_sortData))) < 0 def filterAcceptsRow(self, source_row, source_parent): if self.m_boolVacio: return True filteris = self.filterRole() source_index = self.sourceModel().index(source_row, 0, source_parent) if source_index.isValid() == False: return True key = self.sourceModel().data(source_index, filteris).property(self.m_filterRoles) if self.m_boolstrexp: return key.__contains__( self.m_strexp ) #;//, Qt::CaseInsensitive); el metadata esta en minuscula else: return self.m_reguexp.match(key).hasMatch() #return QString!!!key.contains(self.m_reguexp) @Slot(int, result=int) def getIndexParent(self, index): if index != -1: return (self.mapToSource(self.index(index, 0, QModelIndex()))).row() return -1 @Slot(int, result=int) def getIndexProxy(self, index): if index != -1: return (self.mapFromSource(self.sourceModel().index( index, 0, QModelIndex()))).row() return -1 @Slot(str) def findElis(self, text): textt = text.strip().lower() if textt == "": self.m_boolVacio = True else: self.m_boolVacio = False if textt.__contains__(" "): self.m_boolstrexp = False self.m_reguexp.setPattern(self.reNumaelis(textt)) else: self.m_boolstrexp = True self.m_strexp = textt #//setFilter no es usado al filtra, solo se invoca para que comienze a hacerlo self.setFilterRegExp(QRegExp(text)) @Signal def signalReset(self): pass @Slot() def endFilterOrder(self): # if(m_boolSignalReset){ # //qDebug()<<"termino Filtering"; # m_boolSignalReset=false; # emit signalReset(); # } pass