QRegExp::matchedLength()徹底ガイド:Qtでの正規表現マッチングと長さ取得

2025-05-27

基本的な説明

  • マッチングが失敗した場合、matchedLength()は通常-1を返します。
  • マッチングが成功した場合、matchedLength()はマッチした文字列の文字数を返します。
  • matchedLength()は、indexIn()exactMatch()などのマッチング関数が成功した後でのみ意味を持ちます。
  • QRegExpは、文字列の中で特定のパターン(正規表現)を探し出すために使われます。

使い方と例

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

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

    QString text = "Hello, World!";
    QRegExp rx("World");

    int pos = rx.indexIn(text); // マッチングを試みる

    if (pos >= 0) {
        qDebug() << "Match found at position:" << pos;
        qDebug() << "Matched length:" << rx.matchedLength(); // マッチした長さを取得
    } else {
        qDebug() << "Match not found.";
    }

    return a.exec();
}

この例では、text文字列内で"World"という文字列を正規表現rxを使って検索しています。indexIn()が成功した場合、matchedLength()は"World"の長さである5を返します。



  1. マッチング失敗時の誤った使用

    • エラー
      indexIn()exactMatch()が失敗(-1を返す)した後にmatchedLength()を呼び出すと、予期しない値(通常は-1)が返されます。
    • 対策
      matchedLength()を呼び出す前に、マッチング関数が成功したかどうかを必ず確認してください。
    QRegExp rx("pattern");
    if (rx.indexIn(text) >= 0) { // マッチング成功を確認
        int length = rx.matchedLength();
        // ... lengthを使用 ...
    } else {
        // マッチング失敗時の処理
    }
    
  2. キャプチャグループとの混同

    • エラー
      matchedLength()は、正規表現全体のマッチした長さを返します。キャプチャグループ(括弧で囲まれた部分)の長さを取得したい場合、cap(n)(nはキャプチャグループの番号)で取得した文字列の長さを別途計算する必要があります。
    • 対策
      キャプチャグループの長さを取得するには、cap(n).length()を使用します。
    QRegExp rx("(\\d+)-(\\d+)"); // キャプチャグループを含む正規表現
    if (rx.indexIn("123-456") >= 0) {
        int totalLength = rx.matchedLength(); // 全体の長さ
        int group1Length = rx.cap(1).length(); // 最初のキャプチャグループの長さ
        int group2Length = rx.cap(2).length(); // 2番目のキャプチャグループの長さ
    }
    
  3. 正規表現の誤り

    • エラー
      正規表現自体が間違っていると、期待通りのマッチングが行われず、matchedLength()も誤った値を返す可能性があります。
    • 対策
      正規表現を慎重に確認し、必要に応じてテストツールを使用して検証してください。
  4. グローバルマッチングとの組み合わせ

    • エラー
      グローバルマッチング(setMinimal(false))を使用する場合、indexIn()を繰り返し呼び出す必要があります。matchedLength()は、最後にマッチした結果の長さを返します。
    • 対策
      グローバルマッチングを使用する場合は、ループ内でindexIn()を呼び出し、各マッチ結果のmatchedLength()を取得します。
    QRegExp rx("(\\d+)");
    rx.setMinimal(false);
    QString text = "123 456 789";
    int pos = 0;
    while ((pos = rx.indexIn(text, pos)) != -1) {
        int length = rx.matchedLength();
        qDebug()<< "match found length:" << length;
        pos += length;
    }
    
  5. QRegularExpressionとの比較

    • QRegExpは古いクラスであり、QRegularExpressionが推奨されています。特に複雑な正規表現を扱う場合や、パフォーマンスが重要な場合は、QRegularExpressionの使用を検討してください。QRegularExpressionMatchクラスのcapturedLength()メソッドはQRegExp::matchedLength()と似た機能を提供します。


例1: 基本的なマッチングと長さの取得

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

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

    QString text = "This is a sample text with numbers 12345.";
    QRegExp rx("\\d+"); // 数字の連続を検索

    int pos = rx.indexIn(text);

    if (pos >= 0) {
        qDebug() << "マッチした位置:" << pos;
        qDebug() << "マッチした長さ:" << rx.matchedLength(); // マッチした部分の長さを取得
        qDebug() << "マッチした文字列:" << rx.cap(0); //マッチした文字列を取得
    } else {
        qDebug() << "マッチが見つかりませんでした。";
    }

    return a.exec();
}

この例では、文字列textの中から数字の連続(\\d+)を検索し、マッチした位置と長さを表示します。cap(0)でマッチした文字列自体を取得しています。

例2: キャプチャグループと長さの取得

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

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

    QString text = "Date: 2023-10-27";
    QRegExp rx("(\\d{4})-(\\d{2})-(\\d{2})"); // 年-月-日をキャプチャグループで取得

    int pos = rx.indexIn(text);

    if (pos >= 0) {
        qDebug() << "マッチした位置:" << pos;
        qDebug() << "全体のマッチした長さ:" << rx.matchedLength();

        qDebug() << "年:" << rx.cap(1) << ", 長さ:" << rx.cap(1).length(); // 年のキャプチャグループと長さ
        qDebug() << "月:" << rx.cap(2) << ", 長さ:" << rx.cap(2).length(); // 月のキャプチャグループと長さ
        qDebug() << "日:" << rx.cap(3) << ", 長さ:" << rx.cap(3).length(); // 日のキャプチャグループと長さ
    } else {
        qDebug() << "マッチが見つかりませんでした。";
    }

    return a.exec();
}

この例では、日付の形式(年-月-日)をキャプチャグループで取得し、それぞれのグループの長さと内容を表示します。cap(n)でn番目のキャプチャグループを取得し、.length()でその長さを取得します。

例3: グローバルマッチングと長さの取得

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

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

    QString text = "Numbers: 12, 345, 6789";
    QRegExp rx("\\d+");
    rx.setMinimal(false); // グローバルマッチングを有効化

    int pos = 0;
    while ((pos = rx.indexIn(text, pos)) != -1) {
        qDebug() << "マッチした位置:" << pos;
        qDebug() << "マッチした長さ:" << rx.matchedLength();
        qDebug() << "マッチした文字列:" << rx.cap(0);
        pos += rx.matchedLength(); // 次のマッチング位置を更新
    }

    return a.exec();
}

この例では、setMinimal(false)を使用してグローバルマッチングを有効化し、文字列内のすべての数字の連続を検索します。whileループ内でindexIn()を繰り返し呼び出し、各マッチ結果の長さと内容を表示します。

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

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

    QString text = "日本語のテキスト123";
    QRegExp rx("テキスト");

    int pos = rx.indexIn(text);

    if (pos >= 0) {
        qDebug() << "マッチした位置:" << pos;
        qDebug() << "マッチした長さ(文字数):" << rx.matchedLength();
        qDebug() << "マッチした長さ(バイト数):" << rx.cap(0).toUtf8().size();
    } else {
        qDebug() << "マッチが見つかりませんでした。";
    }

    return a.exec();
}


QRegularExpressionとQRegularExpressionMatchの使用

QRegularExpressionは、QRegExpよりも強力で柔軟な正規表現エンジンを提供します。QRegularExpressionMatchクラスは、マッチング結果を保持し、capturedLength()メソッドでマッチした部分文字列の長さを取得できます。

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

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

    QString text = "This is a sample text with numbers 12345.";
    QRegularExpression rx("\\d+"); // 数字の連続を検索

    QRegularExpressionMatch match = rx.match(text); // マッチングを実行

    if (match.hasMatch()) {
        qDebug() << "マッチした位置:" << match.capturedStart();
        qDebug() << "マッチした長さ:" << match.capturedLength(); // マッチした部分の長さを取得
        qDebug() << "マッチした文字列:" << match.captured(0); //マッチした文字列を取得
    } else {
        qDebug() << "マッチが見つかりませんでした。";
    }

    return a.exec();
}
  • capturedStart()でマッチした開始位置、captured(0)でマッチした文字列を取得できます。
  • QRegularExpressionMatchオブジェクトのcapturedLength()メソッドでマッチした部分の長さを取得します。
  • QRegularExpressionで正規表現を定義し、match()メソッドでマッチングを実行します。

グローバルマッチングとcapturedLength()

QRegularExpressionでグローバルマッチングを行う場合は、globalMatch()メソッドを使用します。

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

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

    QString text = "Numbers: 12, 345, 6789";
    QRegularExpression rx("\\d+");

    QRegularExpressionMatchIterator it = rx.globalMatch(text); // グローバルマッチング

    while (it.hasNext()) {
        QRegularExpressionMatch match = it.next();
        qDebug() << "マッチした位置:" << match.capturedStart();
        qDebug() << "マッチした長さ:" << match.capturedLength();
        qDebug() << "マッチした文字列:" << match.captured(0);
    }

    return a.exec();
}
  • イテレータを使ってマッチ結果を順に処理し、capturedLength()で長さを取得します。
  • globalMatch()でマッチ結果のイテレータを取得します。

キャプチャグループとcapturedLength()

QRegularExpressionでもキャプチャグループを使用できます。

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

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

    QString text = "Date: 2023-10-27";
    QRegularExpression rx("(\\d{4})-(\\d{2})-(\\d{2})");

    QRegularExpressionMatch match = rx.match(text);

    if (match.hasMatch()) {
        qDebug() << "全体のマッチした長さ:" << match.capturedLength(0); //全体のマッチした長さ
        qDebug() << "年:" << match.captured(1) << ", 長さ:" << match.capturedLength(1);
        qDebug() << "月:" << match.captured(2) << ", 長さ:" << match.capturedLength(2);
        qDebug() << "日:" << match.captured(3) << ", 長さ:" << match.capturedLength(3);
    }

    return a.exec();
}
  • captured(n)でn番目のキャプチャグループの文字列を取得します。
  • capturedLength(n)でn番目のキャプチャグループの長さを取得します。

QStringのlength()メソッドとindexOf()メソッドの組み合わせ

正規表現を使用せずに、単純な文字列検索で長さが必要な場合は、QStringindexOf()メソッドとlength()メソッドを組み合わせることもできます。

#include <QCoreApplication>
#include <QString>
#include <QDebug>

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

    QString text = "This is a sample text with numbers 12345.";
    QString searchString = "12345";

    int pos = text.indexOf(searchString);

    if (pos >= 0) {
        qDebug() << "マッチした位置:" << pos;
        qDebug() << "マッチした長さ:" << searchString.length();
    } else {
        qDebug() << "マッチが見つかりませんでした。";
    }

    return a.exec();
}
  • length()で検索文字列の長さを取得します。
  • indexOf()で検索文字列の位置を見つけます。
  • 単純な文字列検索の場合は、QStringのメソッドを組み合わせることも可能です。
  • capturedLength()メソッドは、マッチした部分文字列の長さを取得するために使用します。
  • QRegularExpressionQRegularExpressionMatchは、QRegExpよりも推奨される代替手段です。