MochiuWiki : SUSE, EC, PCB
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
検索
個人用ツール
ログイン
Toggle dark mode
名前空間
ページ
議論
表示
閲覧
ソースを閲覧
履歴を表示
C++の基礎 - 正規表現のソースを表示
提供: MochiuWiki : SUSE, EC, PCB
←
C++の基礎 - 正規表現
あなたには「このページの編集」を行う権限がありません。理由は以下の通りです:
この操作は、次のグループのいずれかに属する利用者のみが実行できます:
管理者
、new-group。
このページのソースの閲覧やコピーができます。
== 概要 == C++において、正規表現はテキストパターンのマッチング、検索、置換等を行うための強力なツールである。<br> C++ 11以降では、標準ライブラリとして<regex>ヘッダが導入されており、正規表現の機能が言語に組み込まれた。<br> <br> これにより、外部ライブラリに頼ることなく正規表現を扱うことができる。<br> <br> 基本的な使用方法としては、<code>std::regex</code>クラスでパターンを定義して、<code>std::regex_match</code>や<code>std::regex_search</code>等のメソッドを使用してマッチングを行う。<br> マッチした結果は、<code>std::smatch</code>クラスで取得できる。<br> <br> 正規表現の構文は、基本的に他の言語やツールで使用されているものと似ているが、いくつか特徴がある。<br> 例えば、文字列リテラルで使用する場合はバックスラッシュを二重に記述する必要がある。<br> これは、C++の文字列エスケープシーケンスの仕様によるものである。<br> <br> パターンマッチングのスタイルは複数用意されており、ECMAScriptスタイル (デフォルト)、basic、extended、awk等から選択できる。<br> 最も一般的に使用されるのはECMAScriptスタイルであり、JavaScriptの正規表現と互換性がある。<br> <br> また、正規表現操作にはいくつかのフラグを設定することができる。<br> 大文字小文字を区別しない検索、複数行モード、より効率的なマッチングのための最適化等を指定できる。<br> <br> エラーハンドリングも重要な要素である。<br> 不正な正規表現パターンを指定した場合、<code>std::regex_error</code>という例外が投げられるため、try-catchブロックでの適切な例外処理が推奨される。<br> <br> C++の正規表現は他の言語と比べて実行速度が遅いことがある。<br> パフォーマンスが重要な場合は、Boostライブラリの正規表現機能や他の文字列処理手法の使用を検討する。<br> <br><br> == 正規表現の使用例 : メールアドレス == 以下の例では、ユーザ名、@記号、ドメイン部分を適切にパターンマッチングしている。<br> <br> <syntaxhighlight lang="c++"> #include <iostream> #include <regex> #include <string> void emailValidation() { try { std::string email = "user@example.com"; std::regex pattern(R"([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})"); if (std::regex_match(email, pattern)) { std::cout << "Valid email address\n"; } } catch (const std::regex_error &e) { std::cerr << "Regex error: " << e.what() << "\nCode: " << e.code() << '\n'; } catch (const std::exception &e) { std::cerr << "Error: " << e.what() << '\n'; } } int main() { try { emailValidation(); } catch (const std::exception &e) { std::cerr << "Main function error: " << e.what() << '\n'; return -1; } return 0; } </syntaxhighlight> <br><br> == 正規表現の使用例 : 電話番号 == 以下の例では、国内の一般的な電話番号形式に対応するパターンを使用している。<br> <br> <syntaxhighlight lang="c++"> #include <iostream> #include <regex> #include <string> void phoneNumberFormat() { try { std::string phone = "090-1234-5678"; std::regex pattern(R"(\d{2,4}-\d{2,4}-\d{4})"); std::smatch matches; if (std::regex_match(phone, matches, pattern)) { std::cout << "Valid phone number" << std::endl ; for (const auto &match : matches) { std::cout << match << std::endl; } } } catch (const std::regex_error &e) { std::cerr << "Regex error: " << e.what() << std::endl; std::cerr << "Code: " << e.code() << std::endl; switch (e.code()) { case std::regex_constants::error_collate: std::cerr << "Invalid collation element request" << std::endl; break; case std::regex_constants::error_ctype: std::cerr << "Invalid character class" << std::endl; break; case std::regex_constants::error_escape: std::cerr << "Invalid escape character or trailing escape" << std::endl; break; case std::regex_constants::error_backref: std::cerr << "Invalid back reference" << std::endl; break; case std::regex_constants::error_brack: std::cerr << "Mismatched brackets" << std::endl; break; case std::regex_constants::error_paren: std::cerr << "Mismatched parentheses" << std::endl; break; case std::regex_constants::error_brace: std::cerr << "Mismatched braces" << std::endl; break; case std::regex_constants::error_badbrace: std::cerr << "Invalid range inside braces" << std::endl; break; case std::regex_constants::error_range: std::cerr << "Invalid character range" << std::endl; break; case std::regex_constants::error_space: std::cerr << "Insufficient memory" << std::endl; break; case std::regex_constants::error_badrepeat: std::cerr << "Invalid repeat expression" << std::endl; break; case std::regex_constants::error_complexity: std::cerr << "Operation too complex" << std::endl; break; case std::regex_constants::error_stack: std::cerr << "Stack space overflow" << std::endl; break; default: std::cerr << "Unknown regex error" << std::endl; break; } } catch (const std::exception &e) { std::cerr << "Error: " << e.what() << std::endl; } } int main() { try { phoneNumberFormat(); } catch (const std::exception &e) { std::cerr << "Main function error: " << e.what() << std::endl; return -1; } return 0; } </syntaxhighlight> <br><br> == 正規表現の使用例 : HTMLタグ == 以下の例では、開始タグと終了タグの対応を確認しながら、HTMLタグの内容を抽出している。<br> <br> <syntaxhighlight lang="c++"> #include <iostream> #include <regex> #include <string> void htmlTagExtraction() { try { std::string html = "<div>Content</div><p>Paragraph</p>"; std::regex pattern("<([a-zA-Z0-9]+)>([^<]+)</\\1>"); std::smatch matches; std::string::const_iterator searchStart(html.cbegin()); while (std::regex_search(searchStart, html.cend(), matches, pattern)) { std::cout << "Tag: " << matches[1] << ", Content: " << matches[2] << std::endl; searchStart = matches.suffix().first; } } catch (const std::regex_error &e) { std::cerr << "Regex error: " << e.what() << std::endl; std::cerr << "Code: " << e.code() << std::endl; } catch (const std::out_of_range &e) { std::cerr << "Out of range error: " << e.what() << std::endl; } catch (const std::exception &e) { std::cerr << "Error: " << e.what() << std::endl; } } int main() { try { htmlTagExtraction(); } catch (const std::exception &e) { std::cerr << "Main function error: " << e.what() << std::endl; return -1; } return 0; } </syntaxhighlight> <br><br> == 正規表現の使用例 : URLの解析 == 以下の例では、プロトコル、ドメイン、ポート番号、パス等の各要素を個別に抽出している。<br> <br> <syntaxhighlight lang="c++"> #include <iostream> #include <regex> #include <string> void urlParsing() { try { std::string url = "https://www.example.com:8080/path?param=value"; std::regex pattern(R"(^(https?):\/\/([^:\/\s]+)(?::(\d+))?(\/[^\s]*)?$)"); std::smatch matches; if (std::regex_match(url, matches, pattern)) { std::cout << "Protocol: " << matches[1] << std::endl; std::cout << "Domain: " << matches[2] << std::endl; std::cout << "Port: " << (matches[3].matched ? matches[3] : "default") << std::endl; std::cout << "Path: " << (matches[4].matched ? matches[4] : "/") << std::endl; } else { std::cerr << "Invalid URL format\n"; } } catch (const std::regex_error &e) { std::cerr << "Regex error in URL parsing: " << e.what() << std::endl; std::cerr << "Code: " << e.code() << std::endl; } catch (const std::out_of_range &e) { std::cerr << "Out of range error in URL parsing: " << e.what() << std::endl; } catch (const std::exception &e) { std::cerr << "Error in URL parsing: " << e.what() << std::endl; } } int main() { try { urlParsing(); } catch (const std::exception &e) { std::cerr << "Main function error: " << e.what() << std::endl; return -1; } return 0; } </syntaxhighlight> <br><br> == 正規表現の使用例 : パスワードの検証 == 以下の例では、大文字、小文字、数字、特殊文字を含む一般的なパスワードポリシーを実装している。<br> <br> <syntaxhighlight lang="c++"> #include <iostream> #include <regex> #include <string> void passwordValidation() { try { std::string password = "Password123!"; std::regex pattern(R"(^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)(?=.*[!@#$%^&*])[A-Za-z\d!@#$%^&*]{8,})$)"); if (std::regex_match(password, pattern)) { std::cout << "Valid password" << std::endl; } else { std::cout << "Invalid password. Password must contain:\n" << "- At least one uppercase letter\n" << "- At least one lowercase letter\n" << "- At least one digit\n" << "- At least one special character (!@#$%^&*)\n" << "- Minimum length of 8 characters\n"; } } catch (const std::regex_error &e) { std::cerr << "Regex error in password validation: " << e.what() << "\nCode: " << e.code() << std::endl; // パターンが複雑な場合の特別なハンドリング if (e.code() == std::regex_constants::error_complexity) { std::cerr << "Password pattern is too complex. Simplifying validation..." << std::endl; // 必要に応じてフォールバックの検証ロジックを実装 } } catch (const std::exception &e) { std::cerr << "Error in password validation: " << e.what() << std::endl; } } int main() { try { passwordValidation(); } catch (const std::exception &e) { std::cerr << "Main function error: " << e.what() << std::endl; return -1; } return 0; } </syntaxhighlight> <br><br> == 正規表現の使用例 : IPアドレスの検証 == 以下の例では、各オクテットの範囲チェックを含む厳密な検証を行っている。<br> <br> <syntaxhighlight lang="c++"> #include <iostream> #include <regex> #include <string> void ipAddressValidation() { try { std::string ip = "192.168.1.1"; std::regex pattern(R"(^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$)"); if (std::regex_match(ip, pattern)) { std::cout << "Valid IP address" << std::endl; // オプション: IPアドレスの種類をチェック std::smatch matches; std::regex privateIpPattern(R"(^(10\.|172\.(1[6-9]|2[0-9]|3[01])\.|192\.168\.).*)"); if (std::regex_match(ip, matches, privateIpPattern)) { std::cout << "Note: This is a private IP address" << std::endl; } } else { std::cerr << "Invalid IP address format" << std::endl; } } catch (const std::regex_error &e) { std::cerr << "Regex error in IP validation: " << e.what() << std::endl; std::cerr << "Code: " << e.code() << std::endl; } catch (const std::exception &e) { std::cerr << "Error in IP validation: " << e.what() << std::endl; } } int main() { try { ipAddressValidation(); } catch (const std::exception &e) { std::cerr << "Main function error: " << e.what() << std::endl; return -1; } return 0; } </syntaxhighlight> <br><br> == 正規表現の使用例 : ログファイルの解析 == 以下の例では、タイムスタンプ、ログレベル、メッセージを分離して抽出している。<br> <br> <syntaxhighlight lang="c++"> #include <iostream> #include <regex> #include <string> void logFileAnalysis() { try { std::string logLine = "[2024-01-01 12:34:56] ERROR: Database connection failed"; std::regex pattern(R"(\[(.*?)\] (\w+): (.*))"); std::smatch matches; if (std::regex_match(logLine, matches, pattern)) { if (matches.size() < 4) { throw std::runtime_error("Invalid log format: insufficient capture groups"); } std::cout << "Timestamp: " << matches[1] << std::endl; std::cout << "Level: " << matches[2] << std::endl; std::cout << "Message: " << matches[3] << std::endl; // ログレベルの検証 std::string level = matches[2]; if (level != "INFO" && level != "WARNING" && level != "ERROR" && level != "DEBUG") { std::cerr << "Warning: Unknown log level " << level << std::endl; } } else { std::cerr << "Invalid log format" << std::endl; } } catch (const std::regex_error &e) { std::cerr << "Regex error in log analysis: " << e.what() << std::endl; std::cerr << "Code: " << e.code() << std::endl; } catch (const std::runtime_error &e) { std::cerr << "Runtime error in log analysis: " << e.what() << std::endl; } catch (const std::exception &e) { std::cerr << "Error in log analysis: " << e.what() << std::endl; } } int main() { try { logFileAnalysis(); } catch (const std::exception &e) { std::cerr << "Main function error: " << e.what() << std::endl; return -1; } return 0; } </syntaxhighlight> <br><br> == 正規表現の使用例 : 日付形式の変換 == 以下の例では、regex_replaceメソッドを使用して日付形式を変更している。<br> <br> <syntaxhighlight lang="c++"> #include <iostream> #include <regex> #include <string> void textReplacement() { try { std::string text = "The date is 2023/12/25 and 2024/01/01"; std::regex pattern(R"((\d{4})/(\d{2})/(\d{2}))"); std::string result = std::regex_replace(text, pattern, "$3-$2-$1"); std::cout << "Transformed: " << result << std::endl; // 置換が行われたか確認 if (result == text) { std::cerr << "Warning: No dates were transformed" << std::endl; } } catch (const std::regex_error &e) { std::cerr << "Regex error in date transformation: " << e.what() << std::endl; std::cerr << "Code: " << e.code() << std::endl; } catch (const std::exception &e) { std::cerr << "Error in date transformation: " << e.what() << std::endl; } } int main() { try { textReplacement(); } catch (const std::exception &e) { std::cerr << "Main function error: " << e.what() << std::endl; return -1; } return 0; } </syntaxhighlight> <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__ [[カテゴリ:C++]]
C++の基礎 - 正規表現
に戻る。
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
Collapse