MochiuWiki : SUSE, EC, PCB
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
検索
個人用ツール
ログイン
Toggle dark mode
名前空間
ページ
議論
表示
閲覧
ソースを閲覧
履歴を表示
Qtの基礎 - 正規表現のソースを表示
提供: MochiuWiki : SUSE, EC, PCB
←
Qtの基礎 - 正規表現
あなたには「このページの編集」を行う権限がありません。理由は以下の通りです:
この操作は、次のグループのいずれかに属する利用者のみが実行できます:
管理者
、new-group。
このページのソースの閲覧やコピーができます。
== 概要 == Qtでは、<code>QRegularExpression</code>クラスを使用して正規表現を扱う。<br> これは現代的な正規表現エンジンを提供しており、Perl互換の正規表現構文をサポートしている。<br> <br> <u>Qt 5.11以前まで使用されていたQRegExpクラスは現在非推奨となっている。</u><br> <br> 基本的な使用方法としては、パターンマッチングとテキスト置換が主な用途である。<br> <br> パターンマッチングでは、文字列が特定のパターンに一致するかどうかを確認する。<br> 例えば、Eメールアドレスの検証やURLの抽出等に活用できる。<br> <br> <code>QRegularExpression</code>クラスには、<u>大文字小文字を区別するオプション</u>、<u>複数行モードの有効化</u>等、様々なオプションを設定することができる。<br> これらのオプションは、パターンマッチングの動作を細かく制御するのに役立つ。<br> <br> マッチング結果は<code>QRegularExpressionMatch</code>オブジェクトとして返されて、マッチした部分文字列や位置情報等の詳細な情報を取得できる。<br> また、グループキャプチャを使用する場合は、パターン内の特定の部分にマッチした文字列を個別に取得することも可能である。<br> <br> 正規表現のパターンが正しく構築されているかどうかを確認する場合は、<code>isValid</code>メソッドで事前に確認できる。<br> これは、実行時エラーを防ぐために重要である。<br> <br> <u>パフォーマンスにおいて、同じパターンを複数回使用する場合は、QRegularExpressionオブジェクトを再利用することを推奨する。</u><br> これにより、パターンの再コンパイルを避けることができる。<br> <br><br> == QRegularExpressionクラス (推奨) == ==== QRegularExpressionクラスとは ==== QRegularExpressionクラスは、PCREライブラリを基盤としており、以下に示すようなメリットがある。<br> * パフォーマンスの向上 : 内部実装が最適化されており、特に複雑なパターンマッチングでより高速に動作する。 * エラーハンドリングの改善 *: マッチング結果やエラー状態をより詳細に把握できるようになった。 *: 以前のQRegExpクラスでは、エラーが発生した際の情報が限定的であった。 * Unicode対応の強化 *: 現代的なテキスト処理に必要な、より包括的なUnicodeサポートを提供している。 <br> QRegularExpressionクラスを使用することにより、コードの保守性が向上して、より堅牢なテキスト処理機能を実装できる。<br> 移行を検討する場合は、既存のQRegExpクラスを使用したコードにおいて、新しい機能の実装時やコードのメンテナンス時に徐々にQRegularExpressionクラスへ移行することが推奨される。<br> <br> QRegularExpressionクラスで頻繁に使用するメソッドを以下に示す。<br> * <code>hasMatch</code>メソッド *: パターンがテキストにマッチしたかどうかをbool値で返す。 *: trueの場合はマッチが成功、falseの場合は失敗を意味する。 * <code>captured</code>メソッド *: マッチした部分文字列や、括弧でグループ化された部分を取得する。 *: 引数無しの場合は完全なマッチを返す。 *: 数値を指定する場合、その番号のキャプチャグループを返す。 *: 文字列を指定する場合、その名前のキャプチャグループを返す。 <br> <u>※注意</u><br> * パターンの最適化 *: 頻繁に使用する正規表現パターンは、オブジェクトとして保持して再利用することにより、パフォーマンスを向上させることができる。 * エラー処理 *: isValidメソッドを使用して、正規表現パターンの妥当性を確認することが推奨される。 <br> ==== QRegularExpressionクラスの使用例 ==== <syntaxhighlight lang="c++"> #include <QRegularExpression> #include <QDebug> class RegexExamples { public: // メールアドレスの検証 static bool validateEmail(const QString& email) { // CaseInsensitiveOptionオプションは、大文字と小文字を区別せずにマッチングを行う QRegularExpression re("^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$", QRegularExpression::CaseInsensitiveOption); QRegularExpressionMatch match = re.match(email); return match.hasMatch(); } // 電話番号からハイフンを除去 static QString normalizePhoneNumber(const QString& phone) { QRegularExpression re("[^0-9]"); return phone.replace(re, ""); } // HTMLタグの抽出 static void extractHtmlTags(const QString& html) { QRegularExpression re("<([a-zA-Z0-9]+)[^>]*>"); QRegularExpressionMatchIterator i = re.globalMatch(html); while (i.hasNext()) { QRegularExpressionMatch match = i.next(); qDebug() << "Found tag:" << match.captured(1); } } // 日付形式の変換 (YYYY/MM/DD -> MM-DD-YYYY) static QString convertDateFormat(const QString& date) { QRegularExpression re("(\\d{4})/(\\d{2})/(\\d{2})"); QRegularExpressionMatch match = re.match(date); if (match.hasMatch()) { return QString("%1-%2-%3").arg(match.captured(2)) .arg(match.captured(3)) .arg(match.captured(1)); } return date; } // 文字列内の数値を抽出して合計を計算 static int sumNumbersInText(const QString& text) { QRegularExpression re("\\d+"); QRegularExpressionMatchIterator i = re.globalMatch(text); int sum = 0; while (i.hasNext()) { QRegularExpressionMatch match = i.next(); sum += match.captured().toInt(); } return sum; } // URLからクエリパラメータを抽出 static QMap<QString, QString> parseQueryParameters(const QString& url) { QMap<QString, QString> params; QRegularExpression re("([^=&?]+)=([^&]*)"); QRegularExpressionMatchIterator i = re.globalMatch(url); while (i.hasNext()) { QRegularExpressionMatch match = i.next(); params[match.captured(1)] = match.captured(2); } return params; } // コードからコメントを抽出 static void extractComments(const QString& code) { // 単一行コメント // MultilineOptionオプションは、複数行のテキストで、行ごとに独立してパターンマッチングを行う // ^ (行頭) と $ (行末) が各行に対して機能する QRegularExpression singleLine("//(.*)$", QRegularExpression::MultilineOption); // 複数行コメント QRegularExpression multiLine("/\\*([^*]|\\*(?!/))*\\*/"); auto processMatch = [](const QRegularExpressionMatch& match) { QString comment = match.captured(0).trimmed(); qDebug() << "Found comment:" << comment; }; // globalMatchメソッドを使用して、テキスト内の全てのマッチを処理 QRegularExpressionMatchIterator i1 = singleLine.globalMatch(code); while (i1.hasNext()) { processMatch(i1.next()); } QRegularExpressionMatchIterator i2 = multiLine.globalMatch(code); while (i2.hasNext()) { processMatch(i2.next()); } } }; </syntaxhighlight> <br> <syntaxhighlight lang="c++"> // 使用例 #include <QDebug> qDebug() << "Email validation: " << RegexExamples::validateEmail("test@example.com"); qDebug() << "Normalized phone: " << RegexExamples::normalizePhoneNumber("123-456-7890"); QString html = "<div>content</div><p>paragraph</p>"; RegexExamples::extractHtmlTags(html); qDebug() << "Converted date: " << RegexExamples::convertDateFormat("2024/03/25"); QString text = "Values: 10, 20, 30"; qDebug() << "Sum of numbers: " << RegexExamples::sumNumbersInText(text); QString url = "https://example.com?name=John&age=25"; QMap<QString, QString> params = RegexExamples::parseQueryParameters(url); qDebug() << "URL parameters:" << params; QString code = "// This is a comment\nint x = 5;\n/* Multi\nline\ncomment */"; RegexExamples::extractComments(code); </syntaxhighlight> <br> ==== CaseInsensitiveOptionオプション ==== <syntaxhighlight lang="c++"> #include <QRegularExpression> #include <QDebug> QRegularExpression reCase("hello", QRegularExpression::CaseInsensitiveOption); QRegularExpressionMatch matchCase = reCase.match("HELLO world"); qDebug() << "Case insensitive match: " << matchCase.hasMatch(); // true </syntaxhighlight> <br> ==== MultilineOptionオプション ==== <syntaxhighlight lang="c++"> #include <QRegularExpression> #include <QDebug> QString multilineText = "Line1\nLine2\nLine3"; QRegularExpression reMulti("^Line", QRegularExpression::MultilineOption); QRegularExpressionMatchIterator i = reMulti.globalMatch(multilineText); while (i.hasNext()) { QRegularExpressionMatch match = i.next(); qDebug() << "Found at position: " << match.capturedStart(); } </syntaxhighlight> <br> ==== キャプチャグループ (数値指定) ==== <syntaxhighlight lang="c++"> #include <QRegularExpression> #include <QDebug> QRegularExpression reGroup("(\\w+)=(\\d+)"); QRegularExpressionMatch matchGroup = reGroup.match("age=25"); if (matchGroup.hasMatch()) { qDebug() << "Full match: " << matchGroup.captured(0); // "age=25" qDebug() << "First group: " << matchGroup.captured(1); // "age" qDebug() << "Second group: " << matchGroup.captured(2); // "25" } </syntaxhighlight> <br> ==== 名前付きキャプチャグループ ==== <syntaxhighlight lang="c++"> #include <QRegularExpression> #include <QDebug> QRegularExpression reNamed("(?<key>\\w+)=(?<value>\\d+)"); QRegularExpressionMatch matchNamed = reNamed.match("count=42"); if (matchNamed.hasMatch()) { qDebug() << "Key: " << matchNamed.captured("key"); // "count" qDebug() << "Value: " << matchNamed.captured("value"); // "42" } </syntaxhighlight> <br> ==== マッチ位置の取得 ==== <syntaxhighlight lang="c++"> #include <QRegularExpression> #include <QDebug> QString text = "Hello, my email is test@example.com and phone is 123-456-7890"; // メールアドレスのパターン QRegularExpression emailRegex(R"(\b[\w\.-]+@[\w\.-]+\.\w+\b)"); // メールアドレスのマッチング QRegularExpressionMatch emailMatch = emailRegex.match(text); if (emailMatch.hasMatch()) { qDebug() << "Match text: " << emailMatch.captured(0); qDebug() << "Start position: " << emailMatch.capturedStart(); qDebug() << "Length: " << emailMatch.capturedLength(); qDebug() << "End position: " << emailMatch.capturedStart() + emailMatch.capturedLength(); } // 電話番号のパターン QRegularExpression phoneRegex(R"(\d{3}-\d{3}-\d{4})"); // 電話番号のマッチング QRegularExpressionMatch phoneMatch = phoneRegex.match(text); if (phoneMatch.hasMatch()) { qDebug() << "Match text: " << phoneMatch.captured(0); qDebug() << "Start position: " << phoneMatch.capturedStart(); qDebug() << "Length: " << phoneMatch.capturedLength(); qDebug() << "End position: " << phoneMatch.capturedStart() + phoneMatch.capturedLength(); } </syntaxhighlight> <br><br> == QRegExpクラス (非推奨) == QRegExpクラスには技術的な限界があり、PCRE (Perl Compatible Regular Expressions) との完全な互換性がなく、現代的な正規表現機能の一部をサポートしていない。<br> 例えば、先読み・後読みのような高度なパターンマッチング機能が制限されている。<br> <br> <u>Qt 5.12以降では、QRegExpクラスの代わりにQRegularExpressionクラスの使用が推奨されている。</u><br> <br> <u>※注意</u><br> <u>パターンに特殊文字を含める場合は、適切にエスケープする必要がある。</u><br> <u>パフォーマンスが重要な場合は、正規表現パターンを事前にコンパイルしておくことを推奨する。</u><br> <br> ==== 基本的なマッチング ==== <syntaxhighlight lang="c++"> // 単純な文字列パターンのマッチング #include <QRegExp> #include <QDebug> QRegExp rx1("hello"); bool match = rx1.exactMatch("hello"); // true qDebug() << "Basic match:" << match; </syntaxhighlight> <br> ==== メタキャラクターを使用したパターン ==== <syntaxhighlight lang="c++"> // \d (数字) や \w (単語文字) 等の特殊文字の使用 #include <QRegExp> #include <QDebug> QRegExp rx2("\\d{3}-\\d{4}"); // 郵便番号パターン qDebug() << "Postal code match:" << rx2.exactMatch("123-4567"); // true </syntaxhighlight> <br> ==== 選択パターン ==== <syntaxhighlight lang="c++"> // | (パイプ) を使用した複数パターンの選択 #include <QRegExp> #include <QDebug> QRegExp rx3("cat|dog"); qDebug() << "Alternative match:" << rx3.exactMatch("cat"); // true qDebug() << "Alternative match:" << rx3.exactMatch("dog"); // true </syntaxhighlight> <br> ==== グループ化とキャプチャ ==== <syntaxhighlight lang="c++"> // ()を使用したグループ化と、capメソッドによるキャプチャ内容の取得 #include <QRegExp> #include <QDebug> QRegExp rx4("(\\w+)@(\\w+\\.\\w+)"); QString text = "contact@example.com"; if (rx4.indexIn(text) != -1) { QString username = rx4.cap(1); // "contact" QString domain = rx4.cap(2); // "example.com" qDebug() << "Username:" << username << "Domain:" << domain; } </syntaxhighlight> <br> ==== 量指定子の使用 ==== <syntaxhighlight lang="c++"> // {n,m}形式での繰り返し回数の指定 #include <QRegExp> #include <QDebug> QRegExp rx5("a{2,4}"); // aが2回から4回 qDebug() << "Quantifier match:" << rx5.exactMatch("aaa"); // true </syntaxhighlight> <br> ==== 文字クラス ==== <syntaxhighlight lang="c++"> // []を使用した文字の範囲指定 #include <QRegExp> #include <QDebug> QRegExp rx6("[A-Za-z0-9]+"); // 英数字の1回以上の繰り返し qDebug() << "Character class match:" << rx6.exactMatch("Test123"); // true </syntaxhighlight> <br> ==== テキスト置換 ==== <syntaxhighlight lang="c++"> // replaceメソッドを使用したパターンマッチング置換 #include <QRegExp> #include <QDebug> QString text2 = "The color is gray."; QRegExp rx7("gray"); text2.replace(rx7, "blue"); qDebug() << "Replaced text:" << text2; // "The color is blue." </syntaxhighlight> <br> ==== 否定文字クラス ==== <syntaxhighlight lang="c++"> // [^...]形式での否定パターン #include <QRegExp> #include <QDebug> QRegExp rx8("[^0-9]+"); // 数字以外の文字の1回以上の繰り返し qDebug() << "Negated class match:" << rx8.exactMatch("ABC"); // true </syntaxhighlight> <br> ==== 位置指定 ==== <syntaxhighlight lang="c++"> // ^ (行頭) や $ (行末) 等のアンカー #include <QRegExp> #include <QDebug> QRegExp rx9("^Start"); // 行頭にStartがあるかチェック qDebug() << "Position match:" << rx9.exactMatch("Start of line"); // true </syntaxhighlight> <br> ==== グリーディマッチとノングリーディマッチ ==== <syntaxhighlight lang="c++"> // .と.?の違いによる最長一致と最短一致の制御 #include <QRegExp> #include <QDebug> QString text3 = "<p>First</p><p>Second</p>"; QRegExp rx10("<p>.*</p>"); // グリーディマッチ QRegExp rx11("<p>.*?</p>"); // ノングリーディマッチ if (rx10.indexIn(text3) != -1) { qDebug() << "Greedy match:" << rx10.cap(0); // "<p>First</p><p>Second</p>" } if (rx11.indexIn(text3) != -1) { qDebug() << "Non-greedy match:" << rx11.cap(0); // "<p>First</p>" } </syntaxhighlight> <br> ==== ワイルドカードモード ==== <syntaxhighlight lang="c++"> // ファイル名パターンマッチング等に使用する簡易的なパターン #include <QRegExp> #include <QDebug> QRegExp rx12("doc*.txt", Qt::CaseSensitive, QRegExp::Wildcard); qDebug() << "Wildcard match:" << rx12.exactMatch("document.txt"); // true </syntaxhighlight> <br><br> == エラー == Qt 6において、<code>QRegExp</code>クラスを使用する場合、以下に示すエラーが発生する。<br> QRegExp was not declared in this scope <br> このエラーは、Qt 6では<code>QRegExp</code>クラスが非推奨となり、<code>QRegularExpression</code>クラスを使用する必要がある。<br> <br> <syntaxhighlight lang="c++"> #include <QRegularExpression> static QRegularExpression RegEx("[+-]"); QString coordinate = "111-222+333"; QStringList parts = coordinate.split(RegEx, Qt::SkipEmptyParts); </syntaxhighlight> <br> <code>QRegularExpression</code>クラスは、より強力で効率的な正規表現エンジンを提供しており、<code>QRegExp</code>クラスと比較していくつかの利点がある。<br> <br><br> {{#seo: |title={{PAGENAME}} : Exploring Electronics and SUSE Linux | MochiuWiki |keywords=MochiuWiki,Mochiu,Wiki,Mochiu Wiki,Electric Circuit,Electric,pcb,Mathematics,AVR,TI,STMicro,AVR,ATmega,MSP430,STM,Arduino,Xilinx,FPGA,Verilog,HDL,PinePhone,Pine Phone,Raspberry,Raspberry Pi,C,C++,C#,Qt,Qml,MFC,Shell,Bash,Zsh,Fish,SUSE,SLE,Suse Enterprise,Suse Linux,openSUSE,open SUSE,Leap,Linux,uCLnux,Podman,電気回路,電子回路,基板,プリント基板 |description={{PAGENAME}} - 電子回路とSUSE Linuxに関する情報 | This page is {{PAGENAME}} in our wiki about electronic circuits and SUSE Linux |image=/resources/assets/MochiuLogo_Single_Blue.png }} __FORCETOC__ [[カテゴリ:Qt]]
Qtの基礎 - 正規表現
に戻る。
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
Collapse