QtのQRegExp::exactMatch()を徹底解説!完全一致の仕組みと使い方

2025-05-27

QRegExp::exactMatch() とは

QRegExp::exactMatch(const QString &str) const は、Qtフレームワークの QRegExp クラスが提供するメンバー関数の一つです。この関数は、正規表現パターンが与えられた文字列全体と完全に一致するかどうかをチェックするために使用されます。

主な特徴と動作

  • 戻り値
    • true: 正規表現パターンが文字列全体と完全に一致した場合。
    • false: 正規表現パターンが文字列全体と一致しない場合(部分一致でも false)。
  • アンカー (^ と $)
    exactMatch() は、正規表現のパターンの先頭に ^ (文字列の先頭に一致) が、末尾に $ (文字列の末尾に一致) が暗黙的に追加されたかのように振る舞います。つまり、パターンが ab で、検索対象の文字列が xabz の場合、match() 関数なら一致しますが、exactMatch()false を返します。exactMatch()true を返すのは、文字列が厳密に ab である場合のみです。
  • 完全一致 (Exact Match)
    exactMatch() は、正規表現パターンが検索対象の文字列の「最初から最後まで」完全に一致する場合にのみ true を返します。文字列の一部が正規表現に一致しても、文字列全体が一致しない場合は false を返します。

使用例

例えば、文字列が数字のみで構成されているかを確認したい場合を考えます。

#include <QCoreApplication>
#include <QDebug>
#include <QRegExp>

int main(int argc, char *argv[]) {
    QCoreApplication a(argc, argv);

    // 数字のみに一致する正規表現 (QRegExpはデフォルトで「*」や「+」が「0回以上」「1回以上」を意味します)
    QRegExp digitRegExp("\\d+"); // \\d は数字に一致、+ は1回以上の繰り返し

    qDebug() << "Testing exactMatch() with digitRegExp:";

    // "12345" は数字のみで構成されているため、完全に一致
    qDebug() << "digitRegExp.exactMatch(\"12345\"): " << digitRegExp.exactMatch("12345"); // true

    // "abc123" は数字以外が含まれているため、完全に一致しない
    qDebug() << "digitRegExp.exactMatch(\"abc123\"): " << digitRegExp.exactMatch("abc123"); // false

    // "123xyz" も同様に、完全に一致しない
    qDebug() << "digitRegExp.exactMatch(\"123xyz\"): " << digitRegExp.exactMatch("123xyz"); // false

    // 空文字列は "+" (1回以上) に一致しないため false
    qDebug() << "digitRegExp.exactMatch(\"\"): " << digitRegExp.exactMatch(""); // false

    // 別の例:特定の単語「apple」に完全に一致するか
    QRegExp appleRegExp("apple");
    qDebug() << "\nTesting exactMatch() with appleRegExp:";
    qDebug() << "appleRegExp.exactMatch(\"apple\"): " << appleRegExp.exactMatch("apple"); // true
    qDebug() << "appleRegExp.exactMatch(\"apples\"): " << appleRegExp.exactMatch("apples"); // false (末尾にsがあるため)
    qDebug() << "appleRegExp.exactMatch(\"an apple\"): " << appleRegExp.exactMatch("an apple"); // false (先頭に"an "があるため)

    return a.exec();
}

このコードを実行すると、以下のような出力が得られます。

Testing exactMatch() with digitRegExp:
digitRegExp.exactMatch("12345"):  true
digitRegExp.exactMatch("abc123"):  false
digitRegExp.exactMatch("123xyz"):  false
digitRegExp.exactMatch(""):  false

Testing exactMatch() with appleRegExp:
appleRegExp.exactMatch("apple"):  true
appleRegExp.exactMatch("apples"):  false
appleRegExp.exactMatch("an apple"):  false

QRegExp::exactMatch()QRegExp::match() / QRegExp::indexIn() との違い

  • match() / search() / indexIn(): 文字列のどこかに正規表現パターンに一致する部分があるかをチェックします。一致が見つかった場合は、その一致の開始位置や長さを返します。
  • exactMatch(): 文字列全体が正規表現パターンと完全に一致するかをチェックします。文字列の途中一致は考慮されません。

exactMatch() は、入力文字列の形式を厳密に検証する場合(例えば、ユーザーが入力した電話番号が正しい形式であるか、またはファイル名が特定のパターンに完全に合致するかなど)に非常に役立ちます。

Qt 5.0 以降では、より強力で標準に準拠した正規表現機能を提供する QRegularExpression クラスが導入され、QRegExp は非推奨 (deprecated) となっています。Qt 6 では QRegExp は完全に削除されました。

もし新しいプロジェクトで正規表現を使用する場合は、QRegularExpression の使用を強く推奨します。QRegularExpressionQRegExp::exactMatch() と同じ振る舞いを実現するには、正規表現パターン自体に明示的に ^$ アンカーを含める必要があります。

例:

#include <QCoreApplication>
#include <QDebug>
#include <QRegularExpression>

int main(int argc, char *argv[]) {
    QCoreApplication a(argc);

    // QRegularExpressionで文字列全体が数字のみであるかをチェック
    // パターンに ^ と $ を含めることで、QRegExp::exactMatch() と同じ効果が得られます
    QRegularExpression digitRegex("^\\d+$");

    qDebug() << "Testing QRegularExpression with ^\\d+$:";

    qDebug() << "digitRegex.match(\"12345\").hasMatch(): " << digitRegex.match("12345").hasMatch(); // true
    qDebug() << "digitRegex.match(\"abc123\").hasMatch(): " << digitRegex.match("abc123").hasMatch(); // false
    qDebug() << "digitRegex.match(\"123xyz\").hasMatch(): " << digitRegex.match("123xyz").hasMatch(); // false

    return a.exec();
}


エスケープシーケンスの誤解(最も一般的)

エラー
正規表現内で特殊文字(., *, +, ?, |, (, ), [, ], {, }, ^, $, \ など)をリテラルとして扱いたいのに、エスケープを忘れる。または、C++の文字列リテラルと正規表現のエスケープが混同される。

具体例

  • バックスラッシュ \ 自体を一致させたい場合は、C++文字列リテラルとして \\ と書き、さらに正規表現のエスケープとして \\\\ と書く必要があります。
  • . (ドット) は正規表現では「任意の一文字」を意味します。もしリテラルのピリオドに一致させたい場合は \. とエスケープが必要です。

トラブルシューティング

  • 生文字列リテラル (Raw String Literals) の利用 (C++11以降)
    C++11からは生文字列リテラルが導入され、エスケープの煩わしさを軽減できます。
    QRegExp rx(R"(\d+\.\d+)"); // "\d+\.\d+" と同じ意味
    
    これは特に複雑な正規表現で役立ちます。
  • 二重エスケープ
    結果として、多くの場合は \ を二重にする必要があります。
    • . をリテラルとしてマッチさせたい場合: QRegExp("\\.")
    • \ をリテラルとしてマッチさせたい場合: QRegExp("\\\\")
  • 正規表現のエスケープを理解する
    正規表現エンジンもまた、一部の文字を特殊な意味で扱います。これらの特殊文字をリテラルとして扱いたい場合は、その前に \ を置く必要があります。
  • C++文字列リテラルのエスケープを理解する
    C++では、\ はエスケープ文字です。例えば、"\n" は改行コード、"\\" はバックスラッシュそのものを意味します。

exactMatch() の意味の誤解(部分一致と完全一致)

エラー
文字列の一部が正規表現に一致すれば exactMatch()true を返すと誤解している。

具体例

  • 正規表現 QRegExp("abc") に対して、文字列 "xabcy" をテストすると false が返されます。これは exactMatch() が文字列全体との完全一致を要求するためです。多くの場合は QRegExp::indexIn()QString::contains(QRegExp) を使うべきだと考えるかもしれません。

トラブルシューティング

  • もし QRegularExpression を使用している場合は、明示的にパターンに ^$ を含める必要があります。
    • QRegularExpression("^abc$")QRegExp("abc").exactMatch() と同等です。
    • QRegularExpression("abc")QRegExp("abc").indexIn() と同等です。
  • もし部分一致を意図している場合は、QRegExp::indexIn() または QString::contains(QRegExp) を使用する。
  • exactMatch() は、正規表現パターンに暗黙的に ^ (文字列の先頭) と $ (文字列の末尾) が追加されたかのように振る舞うことを理解する。

正規表現の構文エラー

エラー
無効な正規表現パターンを QRegExp のコンストラクタに渡している。

具体例

  • サポートされていない正規表現機能を使用する(QRegExp はPerl互換の正規表現機能のサブセットのみをサポートしており、QRegularExpression よりも機能が少ないです)。
  • QRegExp("[a-z") のように閉じ括弧を忘れる。

トラブルシューティング

  • 複雑な正規表現の場合は、オンラインの正規表現テスター(regex101.com など)で試行錯誤し、意図した通りに動作するかを確認する。
  • QRegExp::PatternSyntax を確認・設定する。デフォルトは QRegExp::RegExp (Perl互換) ですが、QRegExp::WildcardQRegExp::FixedString に設定すると、正規表現の解釈が変わります。
  • QRegExp::errorString() を使用して、エラーの詳細を取得する。
    QRegExp rx("[a-z");
    if (!rx.isValid()) {
        qDebug() << "正規表現エラー:" << rx.errorString();
    }
    
  • QRegExp::isValid() を使用して、正規表現が有効であるかを確認する。

大文字・小文字の区別 (Qt::CaseSensitivity)

エラー
大文字・小文字の区別が意図通りに設定されていない。

具体例

  • QRegExp("apple", Qt::CaseSensitive)"Apple" とは一致しない。

トラブルシューティング

  • QRegExp のコンストラクタまたは setCaseSensitivity()Qt::CaseSensitive (デフォルト) か Qt::CaseInsensitive を適切に設定する。
    QRegExp rx("apple", Qt::CaseInsensitive);
    qDebug() << rx.exactMatch("Apple"); // true
    

QRegExp の非推奨化と QRegularExpression への移行

エラー
Qt 5.0以降で QRegExp を使い続けている、またはQt 6に移行した際に QRegExp が見つからない。

具体例

  • Qt 6にアップグレードすると QRegExp がコンパイルエラーになる。
  • QRegExp が多くのバグやパフォーマンスの問題を抱えている古い正規表現エンジンであるため、意図しない挙動や速度低下が発生する。

トラブルシューティング

  • QRegularExpressionexactMatch() のような完全一致の挙動を再現するには、正規表現パターンに明示的に ^$ を追加する必要があることを忘れない。
    // QRegExp rx("pattern").exactMatch(str) に相当
    QRegularExpression regex("^pattern$");
    bool matched = regex.match(str).hasMatch();
    
  • 既存のプロジェクトで QRegExp を使用している場合、段階的に QRegularExpression へ移行することを検討する。
  • 新しいプロジェクトでは QRegularExpression を使用する。

文字エンコーディングの問題

エラー
文字列と正規表現のエンコーディングが一致していない場合、期待通りに動作しないことがある。

  • Qtの文字列 (QString) はUnicodeを内部的に使用しているため、通常はエンコーディングの問題は少ないですが、外部からのデータ(ファイル、ネットワークなど)を扱う場合は、正しいエンコーディングで QString に変換されているかを確認する。


注意
QRegExp はQt 5.0以降で非推奨となり、Qt 6では削除されています。新しいプロジェクトでは QRegularExpression の使用を強く推奨します。これらの例は、主に既存の QRegExp コードを理解するため、または古いQtバージョンで開発する場合を想定しています。

QRegExp::exactMatch() のプログラミング例

すべての例で、QCoreApplication を使用してQtのイベントループを初期化し、qDebug() で結果を出力します。

#include <QCoreApplication>
#include <QDebug>
#include <QRegExp> // QRegExpを使用するために必要

int main(int argc, char *argv[]) {
    QCoreApplication a(argc, argv);

    qDebug() << "--- QRegExp::exactMatch() の使用例 ---";

    // 1. 数字のみの文字列を検証する例
    //    パターン: "\\d+" は1つ以上の数字に一致
    //    exactMatch() は文字列全体がこのパターンに完全に一致するかをチェック
    QRegExp digitRegExp("\\d+");
    qDebug() << "\n=== 例1: 数字のみの文字列の検証 ===";
    qDebug() << "パターン: " << digitRegExp.pattern();

    // 完全に一致する場合
    qDebug() << "exactMatch(\"12345\"): " << digitRegExp.exactMatch("12345"); // true
    qDebug() << "exactMatch(\"0\"): " << digitRegExp.exactMatch("0");     // true

    // 部分的に一致するが、完全に一致しない場合
    qDebug() << "exactMatch(\"abc123def\"): " << digitRegExp.exactMatch("abc123def"); // false
    qDebug() << "exactMatch(\"123.45\"): " << digitRegExp.exactMatch("123.45");     // false (ドットが含まれるため)

    // パターンに一致する部分がない場合
    qDebug() << "exactMatch(\"hello\"): " << digitRegExp.exactMatch("hello");     // false

    // 空文字列は "+" (1回以上) に一致しないため false
    qDebug() << "exactMatch(\"\"): " << digitRegExp.exactMatch("");           // false

    // 2. 特定の単語に完全に一致するかを検証する例
    //    パターン: "apple"
    QRegExp appleRegExp("apple");
    qDebug() << "\n=== 例2: 特定の単語への完全一致 ===";
    qDebug() << "パターン: " << appleRegExp.pattern();

    // 完全に一致する場合
    qDebug() << "exactMatch(\"apple\"): " << appleRegExp.exactMatch("apple");     // true

    // 部分的に一致するが、完全に一致しない場合
    qDebug() << "exactMatch(\"apples\"): " << appleRegExp.exactMatch("apples");   // false (末尾に 's' があるため)
    qDebug() << "exactMatch(\"pineapple\"): " << appleRegExp.exactMatch("pineapple"); // false (先頭に 'pine' があるため)
    qDebug() << "exactMatch(\"an apple\"): " << appleRegExp.exactMatch("an apple"); // false (先頭に 'an ' があるため)
    qDebug() << "exactMatch(\"Apple\"): " << appleRegExp.exactMatch("Apple");     // false (デフォルトで大文字小文字を区別するため)

    // 3. 大文字・小文字を区別しない完全一致の例
    //    コンストラクタで Qt::CaseInsensitive を指定
    QRegExp caseInsensitiveAppleRegExp("apple", Qt::CaseInsensitive);
    qDebug() << "\n=== 例3: 大文字・小文字を区別しない完全一致 ===";
    qDebug() << "パターン: " << caseInsensitiveAppleRegExp.pattern() << ", 大文字小文字区別: なし";

    qDebug() << "exactMatch(\"apple\"): " << caseInsensitiveAppleRegExp.exactMatch("apple"); // true
    qDebug() << "exactMatch(\"Apple\"): " << caseInsensitiveAppleRegExp.exactMatch("Apple"); // true
    qDebug() << "exactMatch(\"APPLE\"): " << caseInsensitiveAppleRegExp.exactMatch("APPLE"); // true
    qDebug() << "exactMatch(\"Apples\"): " << caseInsensitiveAppleRegExp.exactMatch("Apples"); // false

    // 4. 固定文字列として完全一致させる例 (ワイルドカードなどを使わない)
    //    setPatternSyntax() で QRegExp::FixedString を指定
    QRegExp fixedStringRegExp("Hello World");
    fixedStringRegExp.setPatternSyntax(QRegExp::FixedString); // パターンを固定文字列として解釈させる
    qDebug() << "\n=== 例4: 固定文字列としての完全一致 ===";
    qDebug() << "パターン: " << fixedStringRegExp.pattern() << ", シンタックス: FixedString";

    qDebug() << "exactMatch(\"Hello World\"): " << fixedStringRegExp.exactMatch("Hello World"); // true
    qDebug() << "exactMatch(\"Hello World!\"): " << fixedStringRegExp.exactMatch("Hello World!"); // false
    qDebug() << "exactMatch(\" Hello World\"): " << fixedStringRegExp.exactMatch(" Hello World"); // false

    // 5. ワイルドカードを使用した例(Qtのワイルドカードシンタックス)
    //    setPatternSyntax() で QRegExp::Wildcard を指定
    //    `*` は0文字以上の任意文字、`?` は1文字の任意文字
    QRegExp wildcardRegExp("file_*.txt");
    wildcardRegExp.setPatternSyntax(QRegExp::Wildcard);
    qDebug() << "\n=== 例5: ワイルドカードを使用した完全一致 ===";
    qDebug() << "パターン: " << wildcardRegExp.pattern() << ", シンタックス: Wildcard";

    qDebug() << "exactMatch(\"file_report.txt\"): " << wildcardRegExp.exactMatch("file_report.txt"); // true
    qDebug() << "exactMatch(\"file_001.txt\"): " << wildcardRegExp.exactMatch("file_001.txt");     // true
    qDebug() << "exactMatch(\"file_.txt\"): " << wildcardRegExp.exactMatch("file_.txt");         // true
    qDebug() << "exactMatch(\"my_file_report.txt\"): " << wildcardRegExp.exactMatch("my_file_report.txt"); // false
    qDebug() << "exactMatch(\"file_report.log\"): " << wildcardRegExp.exactMatch("file_report.log");     // false

    // 6. QRegularExpressionでの同等の処理 (推奨される現代的な方法)
    //    QRegExp::exactMatch() と同じ挙動には、パターンに '^' (開始) と '$' (終了) を含める必要があります。
    //    これにより、文字列全体との完全一致が保証されます。
    qDebug() << "\n=== 例6: QRegularExpression での同等処理 ===";
    qDebug() << "パターン: \"^\\d+$\" (QRegExp::exactMatch() と同じ効果)";

    QRegularExpression modernDigitRegex("^\\d+$");
    qDebug() << "modernDigitRegex.match(\"12345\").hasMatch(): " << modernDigitRegex.match("12345").hasMatch(); // true
    qDebug() << "modernDigitRegex.match(\"abc123def\").hasMatch(): " << modernDigitRegex.match("abc123def").hasMatch(); // false
    qDebug() << "modernDigitRegex.match(\"\").hasMatch(): " << modernDigitRegex.match("").hasMatch();           // false

    return a.exec();
}

このコードの出力例:

--- QRegExp::exactMatch() の使用例 ---

=== 例1: 数字のみの文字列の検証 ===
パターン: "\d+"
exactMatch("12345"):  true
exactMatch("0"):  true
exactMatch("abc123def"):  false
exactMatch("123.45"):  false
exactMatch("hello"):  false
exactMatch(""):  false

=== 例2: 特定の単語への完全一致 ===
パターン: "apple"
exactMatch("apple"):  true
exactMatch("apples"):  false
exactMatch("pineapple"):  false
exactMatch("an apple"):  false
exactMatch("Apple"):  false

=== 例3: 大文字・小文字を区別しない完全一致 ===
パターン: "apple" , 大文字小文字区別: なし
exactMatch("apple"):  true
exactMatch("Apple"):  true
exactMatch("APPLE"):  true
exactMatch("Apples"):  false

=== 例4: 固定文字列としての完全一致 ===
パターン: "Hello World" , シンタックス: FixedString
exactMatch("Hello World"):  true
exactMatch("Hello World!"):  false
exactMatch(" Hello World"):  false

=== 例5: ワイルドカードを使用した完全一致 ===
パターン: "file_*.txt" , シンタックス: Wildcard
exactMatch("file_report.txt"):  true
exactMatch("file_001.txt"):  true
exactMatch("file_.txt"):  true
exactMatch("my_file_report.txt"):  false
exactMatch("file_report.log"):  false

=== 例6: QRegularExpression での同等処理 ===
パターン: "^\d+$" (QRegExp::exactMatch() と同じ効果)
modernDigitRegex.match("12345").hasMatch():  true
modernDigitRegex.match("abc123def").hasMatch():  false
modernDigitRegex.match(""):  false
  1. 数字のみの文字列の検証
    QRegExp("\\d+") は、1つ以上の数字 (\d) に一致する正規表現です。exactMatch() は、与えられた文字列全体が数字のみで構成されている場合にのみ true を返します。
  2. 特定の単語への完全一致
    QRegExp("apple") は、文字通り "apple" という単語に一致します。exactMatch() は、文字列が厳密に "apple" である場合にのみ true です。
  3. 大文字・小文字を区別しない完全一致
    Qt::CaseInsensitive をコンストラクタに渡すことで、大文字・小文字を区別せずにパターンマッチングを行います。
  4. 固定文字列としての完全一致
    setPatternSyntax(QRegExp::FixedString) を使用すると、正規表現の特殊文字が無視され、パターンが通常の文字列として扱われます。これにより、特定の文字列が入力と完全に一致するかを素早く確認できます。
  5. ワイルドカードを使用した完全一致
    setPatternSyntax(QRegExp::Wildcard) を使用すると、パターン内の *? がファイル名などで使われるワイルドカードとして機能します。これは、正規表現の複雑さを避けたい場合に便利です。
  6. QRegularExpression での同等処理
    Qtの最新の正規表現クラスである QRegularExpression を使用する例です。QRegExp::exactMatch() と同じ「文字列全体との完全一致」の挙動を実現するには、正規表現パターンに明示的に ^ (文字列の先頭) と $ (文字列の末尾) を含める必要があります。


QRegularExpression を使用する (推奨)

Qt 5.0 で導入された QRegularExpression は、Perl互換の正規表現 (PCRE: Perl Compatible Regular Expressions) を提供し、QRegExp よりも強力で現代的な正規表現エンジンです。QRegExp::exactMatch() と同等の機能を実現するには、正規表現パターンに文字列の開始を示す ^ (キャレット) と文字列の終了を示す $ (ダラー) アンカーを明示的に含める必要があります。

QRegExp::exactMatch(str) の代替

#include <QCoreApplication>
#include <QDebug>
#include <QRegularExpression>

int main(int argc, char *argv[]) {
    QCoreApplication a(argc, argv);

    QString testString = "hello world";

    // QRegExp::exactMatch("hello world") と同等
    // パターンに ^ と $ を含めることで、文字列全体との完全一致を強制します
    QRegularExpression regex("^hello world$");

    if (regex.match(testString).hasMatch()) {
        qDebug() << "'" << testString << "' はパターンに完全に一致します。"; // 出力される
    } else {
        qDebug() << "'" << testString << "' はパターンに完全に一致しません。";
    }

    testString = "hello world!";
    if (regex.match(testString).hasMatch()) {
        qDebug() << "'" << testString << "' はパターンに完全に一致します。";
    } else {
        qDebug() << "'" << testString << "' はパターンに完全に一致しません。"; // 出力される
    }

    testString = "  hello world  ";
    if (regex.match(testString).hasMatch()) {
        qDebug() << "'" << testString << "' はパターンに完全に一致します。";
    } else {
        qDebug() << "'" << testString << "' はパターンに完全に一致しません。"; // 出力される
    }

    // 例:数字のみの文字列を検証
    QRegularExpression digitRegex("^\\d+$"); // 1つ以上の数字で始まり、終わる

    qDebug() << "\n--- QRegularExpressionによる数字文字列の検証 ---";
    qDebug() << "'12345' 完全一致: " << digitRegex.match("12345").hasMatch(); // true
    qDebug() << "'123.45' 完全一致: " << digitRegex.match("123.45").hasMatch(); // false
    qDebug() << "'' 完全一致: " << digitRegex.match("").hasMatch();           // false

    return a.exec();
}

利点

  • パフォーマンス
    一般的に QRegExp よりも高速です。
  • PCRE互換
    広く使われているPerl互換正規表現の構文をサポートしており、より表現力豊かで強力なパターンを記述できます。
  • 最新かつ推奨される方法
    Qtの正規表現機能を使用する場合の標準的なアプローチです。

QString の組み込み関数

正規表現を使用するほど複雑でない、単純な文字列の完全一致や、特定の条件を満たすかのチェックであれば、QString クラスが提供する組み込み関数で十分な場合があります。

  • QString::startsWith()QString::endsWith()QString::length() の組み合わせ 文字列が特定のプレフィックスとサフィックスを持ち、かつ全体の長さも一致する場合に、完全一致を模倣できます。これは、より単純なパターンにのみ適用可能です。

    #include <QCoreApplication>
    #include <QDebug>
    #include <QString>
    
    int main(int argc, char *argv[]) {
        QCoreApplication a(argc, argv);
    
        QString fileName = "document.txt";
    
        qDebug() << "\n--- startsWith/endsWith/length の組み合わせ ---";
        bool isDocTxt = fileName.startsWith("document") &&
                        fileName.endsWith(".txt") &&
                        fileName.length() == QString("document.txt").length();
        qDebug() << "fileName == \"document.txt\": " << isDocTxt; // true
    
        return a.exec();
    }
    
  • QString::compare() (大文字小文字を区別しない完全一致) compare() 関数は、Qt::CaseInsensitive オプションを指定することで、大文字小文字を区別せずに文字列を比較できます。戻り値は0であれば等しいことを意味します。

    #include <QCoreApplication>
    #include <QDebug>
    #include <QString>
    
    int main(int argc, char *argv[]) {
        QCoreApplication a(argc, argv);
    
        QString str = "Apple";
    
        qDebug() << "\n--- QString::compare() による大文字小文字を区別しない完全一致 ---";
        qDebug() << "str.compare(\"apple\", Qt::CaseInsensitive) == 0: "
                 << (str.compare("apple", Qt::CaseInsensitive) == 0); // true
    
        return a.exec();
    }
    
  • QString::operator== (完全一致) 最も単純な完全一致のチェックです。大文字小文字の区別を考慮しない場合は、両方の文字列を同じケースに変換してから比較します。

    #include <QCoreApplication>
    #include <QDebug>
    #include <QString>
    
    int main(int argc, char *argv[]) {
        QCoreApplication a(argc, argv);
    
        QString str = "apple";
    
        qDebug() << "\n--- QString::operator== による完全一致 ---";
        qDebug() << "str == \"apple\": " << (str == "apple");             // true
        qDebug() << "str == \"Apple\": " << (str == "Apple");             // false (大文字小文字を区別)
        qDebug() << "str.toLower() == \"apple\": " << (str.toLower() == "Apple".toLower()); // true (大文字小文字を区別しない)
    
        return a.exec();
    }
    

利点

  • パフォーマンス
    単純な文字列操作の場合、正規表現を使用するよりも高速です。
  • シンプルさ
    複雑な正規表現エンジンを必要とせず、コードが読みやすくなります。

ユーザー入力の検証など、特定の用途では QRegularExpressionValidator が非常に便利です。このバリデーターは、QRegExpValidator の現代的な代替であり、自動的にパターンに ^$ アンカーを追加して、入力文字列全体との完全一致をチェックします。

// これはGUIアプリケーションの例なので、QCoreApplicationではなくQApplicationとQLineEditが必要です
#include <QApplication>
#include <QLineEdit>
#include <QRegularExpressionValidator>
#include <QVBoxLayout>
#include <QWidget>
#include <QDebug> // for debugging output in main

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    QWidget window;
    QVBoxLayout *layout = new QVBoxLayout(&window);

    QLineEdit *lineEdit = new QLineEdit(&window);
    layout->addWidget(lineEdit);

    // 数字のみを許可するバリデーター
    // QRegExpValidator と同様に、QRegularExpressionValidator は自動的に ^ と $ を追加します
    QRegularExpression digitRegex("\\d+");
    QRegularExpressionValidator *validator = new QRegularExpressionValidator(digitRegex, &window);
    lineEdit->setValidator(validator);

    // テスト用の入力
    qDebug() << "--- QRegularExpressionValidator の使用例 ---";

    QString testInput1 = "123";
    int pos1 = 0;
    QValidator::State state1 = validator->validate(testInput1, pos1);
    qDebug() << "入力: '" << testInput1 << "', 状態: " << (state1 == QValidator::Acceptable ? "Acceptable" :
                                                      (state1 == QValidator::Intermediate ? "Intermediate" : "Invalid"));
    // 出力: Acceptable (完全に数字のみ)

    QString testInput2 = "abc";
    int pos2 = 0;
    QValidator::State state2 = validator->validate(testInput2, pos2);
    qDebug() << "入力: '" << testInput2 << "', 状態: " << (state2 == QValidator::Acceptable ? "Acceptable" :
                                                      (state2 == QValidator::Intermediate ? "Intermediate" : "Invalid"));
    // 出力: Invalid (数字以外が含まれる)

    QString testInput3 = "12a";
    int pos3 = 0;
    QValidator::State state3 = validator->validate(testInput3, pos3);
    qDebug() << "入力: '" << testInput3 << "', 状態: " << (state3 == QValidator::Acceptable ? "Acceptable" :
                                                      (state3 == QValidator::Intermediate ? "Intermediate" : "Invalid"));
    // 出力: Invalid

    // 空文字列は "+" (1回以上) に一致しないため Invalid
    QString testInput4 = "";
    int pos4 = 0;
    QValidator::State state4 = validator->validate(testInput4, pos4);
    qDebug() << "入力: '" << testInput4 << "', 状態: " << (state4 == QValidator::Acceptable ? "Acceptable" :
                                                      (state4 == QValidator::Intermediate ? "Intermediate" : "Invalid"));
    // 出力: Invalid

    window.show();
    return app.exec();
}

利点

  • 自動的な完全一致
    QRegExpValidator と同様に、バリデーターは内部的に ^$ をパターンに追加するため、開発者はパターンに明示的に含める必要がありません。
  • GUI統合
    QLineEdit などのウィジェットと直接統合され、ユーザー入力のリアルタイム検証に最適です。