Files
pip/libs/main/text/piregularexpression.h
2025-08-14 10:54:37 +03:00

332 lines
15 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*! \file pistring.h
* \ingroup Text
* \brief
* \~english Regular expression
* \~russian Регулярное выражение
*/
/*
PIP - Platform Independent Primitives
Regular expression
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PIREGULAREXPRESSION_H
#define PIREGULAREXPRESSION_H
#include "pistring.h"
//! \ingroup Text
//! \brief Regular expression class
//! \~english Class for working with regular expressions
//! \~russian Класс для работы с регулярными выражениями
//!
class PIP_EXPORT PIRegularExpression {
public:
//! \brief
//! \~english Options for regular expression matching behavior
//! \~russian Опции поведения регулярного выражения
enum Option {
None = 0x0, /*!< \~english No special options \~russian Без специальных опций */
CaseInsensitive = 0x01, /*!< \~english Case insensitive matching \~russian Регистронезависимое сопоставление */
Singleline = 0x02, /*!< \~english Dot matches newline \~russian Точка соответствует символу новой строки */
Multiline = 0x04, /*!< \~english ^ and $ match at line boundaries \~russian ^ и $ соответствуют границам строк */
InvertedGreediness = 0x08, /*!< \~english Quantifiers are non-greedy by default \~russian Квантификаторы по умолчанию нежадные */
Extended = 0x10 /*!< \~english Extended pattern syntax \~russian Расширенный синтаксис шаблона */
};
//! \brief
//! \~english Combination of regular expression options
//! \~russian Комбинация флагов опций регулярного выражения
typedef PIFlags<Option> Options;
//! \brief
//! \~english Creates regular expression with given pattern and options
//! \~russian Создает регулярное выражение с указанным шаблоном и опциями
//! \~english \param pattern Regular expression pattern
//! \~russian \param pattern Шаблон регулярного выражения
//! \~english \param opt Matching options
//! \~russian \param opt Опции сопоставления
PIRegularExpression(const PIString & pattern = {}, Options opt = None);
//! \brief
//! \~english Creates copy of regular expression
//! \~russian Создает копию регулярного выражения
//! \~english \param o Source regular expression
//! \~russian \param o Исходное регулярное выражение
PIRegularExpression(const PIRegularExpression & o);
//! \brief
//! \~english Assigns regular expression
//! \~russian Присваивает регулярное выражение
//! \~english \param o Source regular expression
//! \~russian \param o Исходное регулярное выражение
PIRegularExpression & operator=(const PIRegularExpression & o);
//! \brief
//! \~english Destroys regular expression object
//! \~russian Уничтожает объект регулярного выражения
~PIRegularExpression();
//! \brief
//! \~english Class containing regular expression match results
//! \~russian Класс, содержащий результаты сопоставления регулярного выражения
class PIP_EXPORT Matcher {
friend class PIRegularExpression;
public:
//! \brief
//! \~english Returns true if match was found
//! \~russian Возвращает true, если совпадение найдено
operator bool() const { return hasMatch(); }
//! \brief
//! \~english Returns true if match was found
//! \~russian Возвращает true, если совпадение найдено
bool hasMatch() const;
//! \brief
//! \~english Attempts to find next match in subject string
//! \~russian Пытается найти следующее совпадение в строке
//! \~english \return true if next match was found
//! \~russian \return true, если следующее совпадение найдено
bool next();
//! \brief
//! \~english Returns list of all matched strings
//! \~russian Возвращает список всех совпавших строк
PIStringList matchedStrings() const;
//! \brief
//! \~english Returns matched substring by index
//! \~russian Возвращает совпавшую подстроку по индексу
//! \~english \param index Capture group index (0 for entire match)
//! \~russian \param index Индекс группы захвата (0 для полного совпадения)
PIString matchedString(int index = 0) const;
//! \brief
//! \~english Returns start position of matched substring
//! \~russian Возвращает начальную позицию совпавшей подстроки
//! \~english \param index Capture group index (0 for entire match)
//! \~russian \param index Индекс группы захвата (0 для полного совпадения)
int matchedStart(int index = 0) const;
//! \brief
//! \~english Returns length of matched substring
//! \~russian Возвращает длину совпавшей подстроки
//! \~english \param index Capture group index (0 for entire match)
//! \~russian \param index Индекс группы захвата (0 для полного совпадения)
int matchedSize(int index = 0) const;
//! \brief
//! \~english Returns matched substring by group name
//! \~russian Возвращает совпавшую подстроку по имени группы
//! \~english \param gname Capture group name
//! \~russian \param gname Имя группы захвата
PIString matchedString(const PIString & gname) const;
//! \brief
//! \~english Returns start position of named capture group
//! \~russian Возвращает начальную позицию именованной группы захвата
//! \~english \param gname Capture group name
//! \~russian \param gname Имя группы захвата
int matchedStart(const PIString & gname) const;
//! \brief
//! \~english Returns length of named capture group match
//! \~russian Возвращает длину совпадения именованной группы захвата
//! \~english \param gname Capture group name
//! \~russian \param gname Имя группы захвата
int matchedSize(const PIString & gname) const;
Matcher(Matcher &&) = default;
private:
Matcher(PIRegularExpression * p);
Matcher(const Matcher &) = default;
Matcher & operator=(const Matcher &) = default;
struct Group {
int index = 0;
int size = 0;
};
PIChar * subjectPtr() const;
bool has_match = false;
bool is_error = false;
PIVector<Group> groups;
PIRegularExpression * parent = nullptr;
PIString * subject = nullptr;
PIString subject_own;
size_t start_offset = 0;
};
//! \brief
//! \~english Returns regular expression pattern
//! \~russian Возвращает шаблон регулярного выражения
PIString pattern() const { return pat_; }
//! \brief
//! \~english Returns regular expression options
//! \~russian Возвращает опции регулярного выражения
Options options() const { return opt_; }
//! \brief
//! \~english Sets regular expression pattern
//! \~russian Устанавливает шаблон регулярного выражения
//! \~english \param pattern New pattern
//! \~russian \param pattern Новый шаблон
void setPattern(const PIString & pattern);
//! \brief
//! \~english Sets regular expression pattern and options
//! \~russian Устанавливает шаблон и опции регулярного выражения
//! \~english \param pattern New pattern
//! \~russian \param pattern Новый шаблон
//! \~english \param opt New options
//! \~russian \param opt Новые опции
void setPattern(const PIString & pattern, Options opt);
//! \brief
//! \~english Returns true if regular expression is valid
//! \~russian Возвращает true, если регулярное выражение валидно
bool isValid() const;
//! \brief
//! \~english Returns true if regular expression is not valid
//! \~russian Возвращает true, если регулярное выражение невалидно
bool isNotValid() const { return !isValid(); }
//! \brief
//! \~english Returns error description if pattern is invalid
//! \~russian Возвращает описание ошибки, если шаблон невалиден
PIString errorString() const;
//! \brief
//! \~english Returns position of error in pattern
//! \~russian Возвращает позицию ошибки в шаблоне
int errorPosition() const;
//! \~english Gets the number of capture groups in the pattern
//! \~russian Возвращает количество групп захвата в шаблоне
int captureGroupsCount() const;
//! \~english Gets the list of named capture groups
//! \~russian Возвращает список именованных групп захвата
PIStringList captureGroupNames() const;
//! \~english Gets the name of capture group by index
//! \~russian Возвращает имя группы захвата по индексу
//! \~english \param index Group index
//! \~russian \param index Индекс группы
PIString captureGroupName(int index) const;
//! \~english Gets the index of named capture group
//! \~russian Возвращает индекс именованной группы захвата
//! \~english \param gname Group name
//! \~russian \param gname Имя группы
int captureGroupIndex(const PIString & gname) const;
//! \~english Matches regular expression against deep copy of subject string
//! \~russian Сопоставляет регулярное выражение с внутренней копией строки
//! \~english \param subject String to match against
//! \~russian \param subject Строка для сопоставления
//! \~english \param offset Starting position for matching
//! \~russian \param offset Начальная позиция для сопоставления
Matcher match(const PIString & subject, size_t offset = 0) const;
//! \~english Matches regular expression against subject string
//! \~russian Сопоставляет регулярное выражение со строкой
//! \~english \param subject String to match against
//! \~russian \param subject Строка для сопоставления
//! \~english \param offset Starting position for matching
//! \~russian \param offset Начальная позиция для сопоставления
Matcher match(PIString & subject, size_t offset = 0) const;
//! \~english Matches regular expression against subject string
//! \~russian Сопоставляет регулярное выражение со строкой
//! \~english \param subject String to match against
//! \~russian \param subject Строка для сопоставления
//! \~english \param offset Starting position for matching
//! \~russian \param offset Начальная позиция для сопоставления
Matcher match(PIString && subject, size_t offset = 0) const;
//! \~english Prepere match regular expression against deep copy of subject string
//! \~russian Подготавливает сопоставление регулярного выражения с внутренней копией строки
//! \~english \param subject String to match against
//! \~russian \param subject Строка для сопоставления
//! \~english \param offset Starting position for matching
//! \~russian \param offset Начальная позиция для сопоставления
Matcher matchIterator(const PIString & subject, size_t offset = 0) const;
//! \~english Prepere match regular expression against subject string
//! \~russian Подготавливает сопоставление регулярного выражения со строкой
//! \~english \param subject String to match against
//! \~russian \param subject Строка для сопоставления
//! \~english \param offset Starting position for matching
//! \~russian \param offset Начальная позиция для сопоставления
Matcher matchIterator(PIString & subject, size_t offset = 0) const;
//! \~english Prepere match regular expression against subject string
//! \~russian Подготавливает сопоставление регулярного выражения со строкой
//! \~english \param subject String to match against
//! \~russian \param subject Строка для сопоставления
//! \~english \param offset Starting position for matching
//! \~russian \param offset Начальная позиция для сопоставления
Matcher matchIterator(PIString && subject, size_t offset = 0) const;
//! \~english Creates regular expression from glob pattern
//! \~russian Создает регулярное выражение из glob-шаблона
//! \~english \param pattern Glob pattern
//! \~russian \param pattern Glob-шаблон
//! \~english \param opt Matching options
//! \~russian \param opt Опции сопоставления
static PIRegularExpression fromGlob(const PIString & pattern, Options opt = None);
//! \~english Creates regular expression from POSIX pattern
//! \~russian Создает регулярное выражение из POSIX-шаблона
//! \~english \param pattern POSIX pattern
//! \~russian \param pattern POSIX-шаблон
//! \~english \param opt Matching options
//! \~russian \param opt Опции сопоставления
static PIRegularExpression fromPOSIX(const PIString & pattern, Options opt = None);
private:
void convertFrom(const PIString & pattern, uint type, Options opt);
PRIVATE_DECLARATION(PIP_EXPORT)
PIString pat_;
Options opt_;
};
#endif // PIREGULAREXPRESSION_H