Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-15 10:24:26

0001 // Copyright (C) 2020 Giuseppe D'Angelo <dangelog@gmail.com>.
0002 // Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
0003 // Copyright (C) 2021 The Qt Company Ltd.
0004 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
0005 
0006 #ifndef QREGULAREXPRESSION_H
0007 #define QREGULAREXPRESSION_H
0008 
0009 #include <QtCore/qglobal.h>
0010 #include <QtCore/qstring.h>
0011 #include <QtCore/qstringview.h>
0012 #include <QtCore/qshareddata.h>
0013 #include <QtCore/qvariant.h>
0014 
0015 #include <iterator>
0016 
0017 QT_REQUIRE_CONFIG(regularexpression);
0018 
0019 QT_BEGIN_NAMESPACE
0020 
0021 class QRegularExpressionMatch;
0022 class QRegularExpressionMatchIterator;
0023 struct QRegularExpressionPrivate;
0024 class QRegularExpression;
0025 
0026 QT_DECLARE_QESDP_SPECIALIZATION_DTOR_WITH_EXPORT(QRegularExpressionPrivate, Q_CORE_EXPORT)
0027 
0028 Q_CORE_EXPORT size_t qHash(const QRegularExpression &key, size_t seed = 0) noexcept;
0029 
0030 class Q_CORE_EXPORT QRegularExpression
0031 {
0032 public:
0033     enum PatternOption {
0034         NoPatternOption                = 0x0000,
0035         CaseInsensitiveOption          = 0x0001,
0036         DotMatchesEverythingOption     = 0x0002,
0037         MultilineOption                = 0x0004,
0038         ExtendedPatternSyntaxOption    = 0x0008,
0039         InvertedGreedinessOption       = 0x0010,
0040         DontCaptureOption              = 0x0020,
0041         UseUnicodePropertiesOption     = 0x0040,
0042         // Formerly (no-ops deprecated in 5.12, removed 6.0):
0043         // OptimizeOnFirstUsageOption = 0x0080,
0044         // DontAutomaticallyOptimizeOption = 0x0100,
0045     };
0046     Q_DECLARE_FLAGS(PatternOptions, PatternOption)
0047 
0048     PatternOptions patternOptions() const;
0049     void setPatternOptions(PatternOptions options);
0050 
0051     QRegularExpression();
0052     explicit QRegularExpression(const QString &pattern, PatternOptions options = NoPatternOption);
0053     QRegularExpression(const QRegularExpression &re) noexcept;
0054     QRegularExpression(QRegularExpression &&re) = default;
0055     ~QRegularExpression();
0056     QRegularExpression &operator=(const QRegularExpression &re) noexcept;
0057     QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QRegularExpression)
0058 
0059     void swap(QRegularExpression &other) noexcept { d.swap(other.d); }
0060 
0061     QString pattern() const;
0062     void setPattern(const QString &pattern);
0063 
0064     [[nodiscard]]
0065     bool isValid() const;
0066     qsizetype patternErrorOffset() const;
0067     QString errorString() const;
0068 
0069     int captureCount() const;
0070     QStringList namedCaptureGroups() const;
0071 
0072     enum MatchType {
0073         NormalMatch = 0,
0074         PartialPreferCompleteMatch,
0075         PartialPreferFirstMatch,
0076         NoMatch
0077     };
0078 
0079     enum MatchOption {
0080         NoMatchOption              = 0x0000,
0081         AnchorAtOffsetMatchOption  = 0x0001,
0082         AnchoredMatchOption Q_DECL_ENUMERATOR_DEPRECATED_X(
0083             "Use AnchorAtOffsetMatchOption instead") = AnchorAtOffsetMatchOption, // Rename@Qt6.0
0084         DontCheckSubjectStringMatchOption = 0x0002
0085     };
0086     Q_DECLARE_FLAGS(MatchOptions, MatchOption)
0087 
0088     [[nodiscard]]
0089     QRegularExpressionMatch match(const QString &subject,
0090                                   qsizetype offset          = 0,
0091                                   MatchType matchType       = NormalMatch,
0092                                   MatchOptions matchOptions = NoMatchOption) const;
0093 
0094 #if QT_DEPRECATED_SINCE(6, 8)
0095     [[nodiscard]]
0096     QT_DEPRECATED_VERSION_X_6_8("Use matchView instead.")
0097     QRegularExpressionMatch match(QStringView subjectView,
0098                                   qsizetype offset          = 0,
0099                                   MatchType matchType       = NormalMatch,
0100                                   MatchOptions matchOptions = NoMatchOption) const;
0101 #endif
0102 
0103     [[nodiscard]]
0104     QRegularExpressionMatch matchView(QStringView subjectView,
0105                                       qsizetype offset          = 0,
0106                                       MatchType matchType       = NormalMatch,
0107                                       MatchOptions matchOptions = NoMatchOption) const;
0108 
0109     [[nodiscard]]
0110     QRegularExpressionMatchIterator globalMatch(const QString &subject,
0111                                                 qsizetype offset          = 0,
0112                                                 MatchType matchType       = NormalMatch,
0113                                                 MatchOptions matchOptions = NoMatchOption) const;
0114 
0115 #if QT_DEPRECATED_SINCE(6, 8)
0116     [[nodiscard]]
0117     QT_DEPRECATED_VERSION_X_6_8("Use globalMatchView instead.")
0118     QRegularExpressionMatchIterator globalMatch(QStringView subjectView,
0119                                                 qsizetype offset          = 0,
0120                                                 MatchType matchType       = NormalMatch,
0121                                                 MatchOptions matchOptions = NoMatchOption) const;
0122 #endif
0123 
0124     [[nodiscard]]
0125     QRegularExpressionMatchIterator globalMatchView(QStringView subjectView,
0126                                                     qsizetype offset          = 0,
0127                                                     MatchType matchType       = NormalMatch,
0128                                                     MatchOptions matchOptions = NoMatchOption) const;
0129 
0130     void optimize() const;
0131 
0132     enum WildcardConversionOption {
0133         DefaultWildcardConversion = 0x0,
0134         UnanchoredWildcardConversion = 0x1,
0135         NonPathWildcardConversion = 0x2,
0136     };
0137     Q_DECLARE_FLAGS(WildcardConversionOptions, WildcardConversionOption)
0138 
0139     static QString escape(const QString &str)
0140     {
0141         return escape(qToStringViewIgnoringNull(str));
0142     }
0143 
0144     static QString wildcardToRegularExpression(const QString &str, WildcardConversionOptions options = DefaultWildcardConversion)
0145     {
0146         return wildcardToRegularExpression(qToStringViewIgnoringNull(str), options);
0147     }
0148 
0149     static inline QString anchoredPattern(const QString &expression)
0150     {
0151         return anchoredPattern(qToStringViewIgnoringNull(expression));
0152     }
0153 
0154     static QString escape(QStringView str);
0155     static QString wildcardToRegularExpression(QStringView str, WildcardConversionOptions options = DefaultWildcardConversion);
0156     static QString anchoredPattern(QStringView expression);
0157 
0158     static QRegularExpression fromWildcard(QStringView pattern, Qt::CaseSensitivity cs = Qt::CaseInsensitive,
0159                                            WildcardConversionOptions options = DefaultWildcardConversion);
0160 #if QT_CORE_REMOVED_SINCE(6, 8)
0161     bool operator==(const QRegularExpression &re) const;
0162     inline bool operator!=(const QRegularExpression &re) const { return !operator==(re); }
0163 #endif
0164 private:
0165     friend Q_CORE_EXPORT bool comparesEqual(const QRegularExpression &lhs,
0166                                             const QRegularExpression &rhs) noexcept;
0167     Q_DECLARE_EQUALITY_COMPARABLE(QRegularExpression)
0168 
0169     friend struct QRegularExpressionPrivate;
0170     friend class QRegularExpressionMatch;
0171     friend struct QRegularExpressionMatchPrivate;
0172     friend class QRegularExpressionMatchIterator;
0173     friend Q_CORE_EXPORT size_t qHash(const QRegularExpression &key, size_t seed) noexcept;
0174 
0175     QRegularExpression(QRegularExpressionPrivate &dd);
0176     QExplicitlySharedDataPointer<QRegularExpressionPrivate> d;
0177 };
0178 
0179 Q_DECLARE_SHARED(QRegularExpression)
0180 Q_DECLARE_OPERATORS_FOR_FLAGS(QRegularExpression::PatternOptions)
0181 Q_DECLARE_OPERATORS_FOR_FLAGS(QRegularExpression::MatchOptions)
0182 Q_DECLARE_OPERATORS_FOR_FLAGS(QRegularExpression::WildcardConversionOptions)
0183 
0184 #ifndef QT_NO_DATASTREAM
0185 Q_CORE_EXPORT QDataStream &operator<<(QDataStream &out, const QRegularExpression &re);
0186 Q_CORE_EXPORT QDataStream &operator>>(QDataStream &in, QRegularExpression &re);
0187 #endif
0188 
0189 #ifndef QT_NO_DEBUG_STREAM
0190 Q_CORE_EXPORT QDebug operator<<(QDebug debug, const QRegularExpression &re);
0191 Q_CORE_EXPORT QDebug operator<<(QDebug debug, QRegularExpression::PatternOptions patternOptions);
0192 #endif
0193 
0194 struct QRegularExpressionMatchPrivate;
0195 QT_DECLARE_QESDP_SPECIALIZATION_DTOR_WITH_EXPORT(QRegularExpressionMatchPrivate, Q_CORE_EXPORT)
0196 
0197 class Q_CORE_EXPORT QRegularExpressionMatch
0198 {
0199 public:
0200     QRegularExpressionMatch();
0201     ~QRegularExpressionMatch();
0202     QRegularExpressionMatch(const QRegularExpressionMatch &match);
0203     QRegularExpressionMatch(QRegularExpressionMatch &&match) = default;
0204     QRegularExpressionMatch &operator=(const QRegularExpressionMatch &match);
0205     QRegularExpressionMatch &operator=(QRegularExpressionMatch &&match) noexcept
0206     { d.swap(match.d); return *this; }
0207     void swap(QRegularExpressionMatch &other) noexcept { d.swap(other.d); }
0208 
0209     QRegularExpression regularExpression() const;
0210     QRegularExpression::MatchType matchType() const;
0211     QRegularExpression::MatchOptions matchOptions() const;
0212 
0213     bool hasMatch() const;
0214     bool hasPartialMatch() const;
0215 
0216     bool isValid() const;
0217 
0218     int lastCapturedIndex() const;
0219 
0220 #if QT_CORE_REMOVED_SINCE(6, 8)
0221     bool hasCaptured(const QString &name) const
0222     { return hasCaptured(qToAnyStringViewIgnoringNull(name)); }
0223     bool hasCaptured(QStringView name) const;
0224 #endif
0225     bool hasCaptured(QAnyStringView name) const;
0226     bool hasCaptured(int nth) const;
0227 
0228     QString captured(int nth = 0) const;
0229     QStringView capturedView(int nth = 0) const;
0230 
0231 #if QT_CORE_REMOVED_SINCE(6, 8)
0232     QString captured(const QString &name) const
0233     { return captured(qToAnyStringViewIgnoringNull(name)); }
0234 
0235     QString captured(QStringView name) const;
0236     QStringView capturedView(QStringView name) const;
0237 #endif
0238     QString captured(QAnyStringView name) const;
0239     QStringView capturedView(QAnyStringView name) const;
0240 
0241     QStringList capturedTexts() const;
0242 
0243     qsizetype capturedStart(int nth = 0) const;
0244     qsizetype capturedLength(int nth = 0) const;
0245     qsizetype capturedEnd(int nth = 0) const;
0246 
0247 #if QT_CORE_REMOVED_SINCE(6, 8)
0248     qsizetype capturedStart(const QString &name) const
0249     { return capturedStart(qToAnyStringViewIgnoringNull(name)); }
0250     qsizetype capturedLength(const QString &name) const
0251     { return capturedLength(qToAnyStringViewIgnoringNull(name)); }
0252     qsizetype capturedEnd(const QString &name) const
0253     { return capturedEnd(qToAnyStringViewIgnoringNull(name)); }
0254 
0255     qsizetype capturedStart(QStringView name) const;
0256     qsizetype capturedLength(QStringView name) const;
0257     qsizetype capturedEnd(QStringView name) const;
0258 #endif
0259     qsizetype capturedStart(QAnyStringView name) const;
0260     qsizetype capturedLength(QAnyStringView name) const;
0261     qsizetype capturedEnd(QAnyStringView name) const;
0262 
0263 private:
0264     friend class QRegularExpression;
0265     friend struct QRegularExpressionMatchPrivate;
0266     friend class QRegularExpressionMatchIterator;
0267 
0268     QRegularExpressionMatch(QRegularExpressionMatchPrivate &dd);
0269     QExplicitlySharedDataPointer<QRegularExpressionMatchPrivate> d;
0270 };
0271 
0272 Q_DECLARE_SHARED(QRegularExpressionMatch)
0273 
0274 #ifndef QT_NO_DEBUG_STREAM
0275 Q_CORE_EXPORT QDebug operator<<(QDebug debug, const QRegularExpressionMatch &match);
0276 #endif
0277 
0278 namespace QtPrivate {
0279 class QRegularExpressionMatchIteratorRangeBasedForIterator;
0280 class QRegularExpressionMatchIteratorRangeBasedForIteratorSentinel {};
0281 }
0282 
0283 struct QRegularExpressionMatchIteratorPrivate;
0284 QT_DECLARE_QESDP_SPECIALIZATION_DTOR_WITH_EXPORT(QRegularExpressionMatchIteratorPrivate, Q_CORE_EXPORT)
0285 
0286 class Q_CORE_EXPORT QRegularExpressionMatchIterator
0287 {
0288 public:
0289     QRegularExpressionMatchIterator();
0290     ~QRegularExpressionMatchIterator();
0291     QRegularExpressionMatchIterator(const QRegularExpressionMatchIterator &iterator);
0292     QRegularExpressionMatchIterator(QRegularExpressionMatchIterator &&iterator) = default;
0293     QRegularExpressionMatchIterator &operator=(const QRegularExpressionMatchIterator &iterator);
0294     QRegularExpressionMatchIterator &operator=(QRegularExpressionMatchIterator &&iterator) noexcept
0295     { d.swap(iterator.d); return *this; }
0296     void swap(QRegularExpressionMatchIterator &other) noexcept { d.swap(other.d); }
0297 
0298     bool isValid() const;
0299 
0300     bool hasNext() const;
0301     QRegularExpressionMatch next();
0302     QRegularExpressionMatch peekNext() const;
0303 
0304     QRegularExpression regularExpression() const;
0305     QRegularExpression::MatchType matchType() const;
0306     QRegularExpression::MatchOptions matchOptions() const;
0307 
0308 private:
0309     friend class QRegularExpression;
0310     friend Q_CORE_EXPORT QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator begin(const QRegularExpressionMatchIterator &iterator);
0311     friend QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIteratorSentinel end(const QRegularExpressionMatchIterator &) { return {}; }
0312 
0313     QRegularExpressionMatchIterator(QRegularExpressionMatchIteratorPrivate &dd);
0314     QExplicitlySharedDataPointer<QRegularExpressionMatchIteratorPrivate> d;
0315 };
0316 
0317 namespace QtPrivate {
0318 
0319 // support for range-based for loop
0320 class QRegularExpressionMatchIteratorRangeBasedForIterator
0321 {
0322 public:
0323     using value_type = QRegularExpressionMatch;
0324     using difference_type = int;
0325     using reference_type = const QRegularExpressionMatch &;
0326     using pointer_type = const QRegularExpressionMatch *;
0327     using iterator_category = std::forward_iterator_tag;
0328 
0329     QRegularExpressionMatchIteratorRangeBasedForIterator()
0330         : m_atEnd(true)
0331     {
0332     }
0333 
0334     explicit QRegularExpressionMatchIteratorRangeBasedForIterator(const QRegularExpressionMatchIterator &iterator)
0335         : m_matchIterator(iterator),
0336         m_currentMatch(),
0337         m_atEnd(false)
0338     {
0339         ++*this;
0340     }
0341 
0342     const QRegularExpressionMatch &operator*() const
0343     {
0344         Q_ASSERT_X(!m_atEnd, Q_FUNC_INFO, "operator* called on an iterator already at the end");
0345         return m_currentMatch;
0346     }
0347 
0348     QRegularExpressionMatchIteratorRangeBasedForIterator &operator++()
0349     {
0350         Q_ASSERT_X(!m_atEnd, Q_FUNC_INFO, "operator++ called on an iterator already at the end");
0351         if (m_matchIterator.hasNext()) {
0352             m_currentMatch = m_matchIterator.next();
0353         } else {
0354             m_currentMatch = QRegularExpressionMatch();
0355             m_atEnd = true;
0356         }
0357 
0358         return *this;
0359     }
0360 
0361     QRegularExpressionMatchIteratorRangeBasedForIterator operator++(int)
0362     {
0363         QRegularExpressionMatchIteratorRangeBasedForIterator i = *this;
0364         ++*this;
0365         return i;
0366     }
0367 
0368 private:
0369     // [input.iterators] imposes operator== on us. Unfortunately, it's not
0370     // trivial to implement, so just do the bare minimum to satifisfy
0371     // Cpp17EqualityComparable.
0372     friend bool comparesEqual(const QRegularExpressionMatchIteratorRangeBasedForIterator &lhs,
0373                               const QRegularExpressionMatchIteratorRangeBasedForIterator &rhs)
0374             noexcept
0375     {
0376         return (&lhs == &rhs);
0377     }
0378     Q_DECLARE_EQUALITY_COMPARABLE(QRegularExpressionMatchIteratorRangeBasedForIterator)
0379 
0380     // This is what we really use in a range-based for.
0381     friend bool comparesEqual(const QRegularExpressionMatchIteratorRangeBasedForIterator &lhs,
0382                               const QRegularExpressionMatchIteratorRangeBasedForIteratorSentinel &rhs)
0383             noexcept
0384     {
0385         Q_UNUSED(rhs);
0386         return lhs.m_atEnd;
0387     }
0388     Q_DECLARE_EQUALITY_COMPARABLE(QRegularExpressionMatchIteratorRangeBasedForIterator,
0389                                   QRegularExpressionMatchIteratorRangeBasedForIteratorSentinel)
0390 
0391     QRegularExpressionMatchIterator m_matchIterator;
0392     QRegularExpressionMatch m_currentMatch;
0393     bool m_atEnd;
0394 };
0395 
0396 } // namespace QtPrivate
0397 
0398 Q_DECLARE_SHARED(QRegularExpressionMatchIterator)
0399 
0400 QT_END_NAMESPACE
0401 
0402 #endif // QREGULAREXPRESSION_H