正規表現の概要とC++11での簡単な使用

7691 ワード

正規表現(regular expression)はコンピュータ科学における概念であり、規則表現とも呼ばれ、通常regex、regexp、RE、regexps、regexes、regexenと略記される.
正規表現はテキストモードです.正規表現は、強力で便利で効率的なテキスト処理ツールです.正規表現自体に、ポケットプログラミング言語のような汎用モード表現(general pattern notation)を加え、使用者にテキストを記述し分析する能力を与える.正規表現は、特定のツールが提供する追加のサポートに合わせて、さまざまなタイプのテキストとデータを追加、削除、分離、重ね合わせ、挿入、修正できます.
完全な正規表現は、特殊文字(special characters)を「メタ文字」(meta characters)と呼び、その他を「文字」(literal)、またはアルファベット、数字、漢字、下線などの普通のテキスト文字(normal text characters)と呼ぶ2つの文字で構成されています.正規表現のメタ文字は、より強力な記述能力を提供します.
テキストエディタと同様に、ほとんどの高度なプログラミング言語では、Perl、Java、Python、C/C++などの正規表現がサポートされています.これらの言語には、それぞれの正規表現パッケージがあります.
正規表現は1つの文字列にすぎず、長さに制限はありません.「サブエクスプレッション」は、正規表現全体の一部を指し、通常はカッコ内のエクスプレッション、または「|」で分割された複数選択されたブランチです.
デフォルトでは、式のアルファベットは大文字と小文字を区別します.
一般的なメタ文字:
1. “.”: 「」以外の任意の文字を一致させ、「」を含む任意の文字を一致させるには、「[sS]」などのモードを使用します.
2."^":入力文字列の開始位置に一致し、任意の文字に一致せず、一致する"^"文字自体は、"^";
3."$":入力文字列の最後の位置に一致し、文字に一致しない場合は、"$"文字自体に一致するには、"$";
4.「*」:前の文字またはサブ式を0回または複数回一致させ、「*」は「{0,}」に等しく、例えば「^*b」は「b」、「^b」、「^b」、...;
5.「+」:前の文字またはサブ式を1回または複数回一致させ、「{1,}」に等しく、例えば「a+b」は「ab」、「aaab」、「aaab」、...;
6. “?”: 前の文字またはサブ式を0回または1回一致させ、「a[cd]?」のような「{0,1}」に等しい.「a」、「ac」、「ad」と一致することができる.この文字が他の制限子「*」、「+」、「?」{n},"{n,},"{n,m}」の後にマッチングモードが「欲張りではない」となる.「欲張りでない」モードは、検索された可能な限り短い文字列に一致し、デフォルトの「欲張り」モードは、検索された可能な限り長い文字列に一致します.たとえば、文字列「oooo」で「o+?」単一の「o」のみが一致し、「o+」はすべての「o」が一致する.
7.「|」:2つの一致条件を論理「または」(Or)演算し、例えば正規表現(him|her)」は「itbelongs to him」と「it belongs to her」に一致するが、「itbelongs to them」には一致しない.
8."":次の文字を特殊文字、テキスト、逆参照、または8進数エスケープとしてマークします.たとえば、"n"一致文字"n","一致改行文字,シーケンス"\一致","(";
9.「w」:アルファベットまたは数字または下線、任意のアルファベットまたは数字または下線、すなわちA~Z,a~z,0~9,のいずれかを選択します.
10.「W」:アルファベット、数字、下線でない任意の文字を一致させる.
11.「s」:スペース、タブ、改ページなどの空白文字のいずれかを含む任意の空白文字に一致し、「[frtv」と等価である.
12.「S」:空白でない任意の文字を一致させ、「^frtv」と等価である.
13.「d」:一致する数字、任意の数字、0~9のいずれかであり、「[0-9]」に等しい.
14.「D」:任意の数字以外の文字に一致し、「^0-9」に等しい.
15.「b」:単語とスペースの間の位置、すなわち単語とスペースの間の位置を一致させ、「erb」は「never」の「er」に一致するが、「verb」の「er」に一致しないなど、任意の文字に一致しない.
16.「B」:非ワード境界マッチング、「erB」は「verb」の「er」に一致するが、「never」の「er」に一致しない.
17.「f」:「x 0 c」と「cL」に等しいページング記号を一致させる.
18.「」:改行記号を一致させ、「x 0 a」と「cJ」に等しい.
19.「r」:リターン記号を一致させ、「x 0 d」と「cM」に等価である.
20.「t」:タブを一致させ、「x 09」と「cI」に等価である.
21.「v」:垂直タブに一致し、「x 0 b」と「cK」に等しい.
22.「cx」:一致するx」が示す制御文字、例えば、cMはControl-Mまたはリターンバーに一致し、「x」の値は「A-Z」または「a-z」の間でなければならない.そうでなければ、cは「c」文字そのものであると仮定する.
23.「{n}」:「n」は非負の整数であり、ちょうどn回一致する.例えば、「o{2}」は「Bob」の「o」と一致しないが、「food」の2つの「o」と一致する.
24.「{n,}」:」nは非負の整数であり、少なくともn回一致する.例えば、「o{2,}」は「Bob」の「o」に一致せず、「foooood」のすべての「o」に一致し、「o{1,}」は「o+」に等価であり、「o{0,}」は「o*」に等価である.
25.「{n,m}」:「n」および「m」は非負の整数であり、n<=mであり、少なくともn回、最大m回、例えば「o{1,3}」は「fooooood」の最初の3つのoに一致し、「o{0,1}」は「o?」に等しい.カンマと数値の間にスペースを挿入することはできません.例えば、「ba{1,3}」は、「ba」または「baa」または「baaa」と一致することができる.
26.「x|y」:xまたはyに一致する.例えば、「z|food」は「z」または「food」に一致する.(z|f)oodは「zood」または「food」に一致する.
27.「[xyz]」:文字セット、一致に含まれる任意の文字、例えば「[abc]」は「plain」の「a」に一致する.
28.「^xyz」:反転文字セット、含まれていない任意の文字を一致させ、「xyz」以外の任意の文字を一致させる.例えば、「[^abc]」は「plain」の「p」に一致する.
29.「[a-z]」:指定した範囲内の任意の文字に一致する文字範囲.例えば、「[a-z]」は「a」から「z」の範囲内の任意の小文字に一致する.
30.「^a-z」:指定された範囲内にない任意の文字を一致させる逆範囲文字.例えば、「^a-z」は「a」から「z」の範囲内にない任意の文字を一致させる.
31.「()」:「(」(「和」)」の間の式を「グループ」グループグループとして定義し、この式に一致する文字を一時領域に保存し、正規表現のうち最大9個を保存することができ、それらは「1」から「9」の記号で参照することができる.
32.「(pattern)」:patternと一致し、一致するサブ式を取得し、$0...$9属性を使用して結果の一致から取得できます.
33.「(?:pattern」:patternに一致するが一致しないサブエクスプレッション、すなわち、後で使用するマッチングを格納しない非キャプチャマッチングであり、これは「or」文字(|)」を使用してモード部品を組み合わせる場合に有用であり、例えば、「industr(?:y|ies)」は「industry|industries」よりも簡略なエクスプレッションである.
34.「(?=pattern」:一致を取得せず、順方向肯定的に事前調査し、検索文字列を一致させる.この一致は後で使用するために取得する必要はない.例えば、「Windows(?=95|98|NT|2000)」は「Windows 2000」の「Windows」と一致するが、「Windows 3.1」の「Windows」と一致しない.プリフェッチは文字を消費しない.すなわち、1つのマッチングが発生した後、最後のマッチングの直後に、プリフェッチを含む文字の後ではなく、次のマッチングの検索を開始する.
35.「(?!pattern」:一致を取得せず、順方向否定事前調査を行い、一致しないpatternの文字列の先頭で検索文字列を一致させ、この一致は後で使用するために取得する必要はありません.「Windows(?!95|98|NT|2000)」のように、「Windows 3.1」の「Windows」には一致するが、「Windows 2000」の「Windows」には一致しない.
特定の特殊文字に一致するには、この特殊文字の前に""を付けます."^","$","(",")","[,"]],"{","}",".","?","+","*","|"が必要です.
C++/C++11では、GCCバージョンは4.9である.0以上、VSバージョンがVS 2013以上の場合、regexヘッダファイルがあり、このヘッダファイルにregex_があるmatch、regex_search、regex_replaceなどの関数は呼び出すことができます.以下はテストコードです.
#include "regex.hpp"
#include 
#include 
#include 
#include 

int test_regex_match()
{
	std::string pattern{ "\\d{3}-\\d{8}|\\d{4}-\\d{7}" }; // fixed telephone
	std::regex re(pattern);

	std::vector<:string> str{ "010-12345678", "0319-9876543", "021-123456789"};

	/* std::regex_match:
		         (  re)          str,         
		  ,                  ,    false;           ,  true
	*/

	for (auto tmp : str) {
		bool ret = std::regex_match(tmp, re);
		if (ret) fprintf(stderr, "%s, can match
", tmp.c_str()); else fprintf(stderr, "%s, can not match
", tmp.c_str()); } return 0; } int test_regex_search() { std::string pattern{ "http|hppts://\\w*$" }; // url std::regex re(pattern); std::vector<:string> str{ "http://blog.csdn.net/fengbingchun", "https://github.com/fengbingchun", "abcd://124.456", "abcd https://github.com/fengbingchun 123" }; /* std::regex_search: regex_match, regex_search , re */ for (auto tmp : str) { bool ret = std::regex_search(tmp, re); if (ret) fprintf(stderr, "%s, can search
", tmp.c_str()); else fprintf(stderr, "%s, can not search
", tmp.c_str()); } return 0; } int test_regex_search2() { std::string pattern{ "[a-zA-z]+://[^\\s]*" }; // url std::regex re(pattern); std::string str{ "my csdn blog addr is: http://blog.csdn.net/fengbingchun , my github addr is: https://github.com/fengbingchun " }; std::smatch results; while (std::regex_search(str, results, re)) { for (auto x : results) std::cout << x << " "; std::cout << std::endl; str = results.suffix().str(); } return 0; } int test_regex_replace() { std::string pattern{ "\\d{18}|\\d{17}X" }; // id card std::regex re(pattern); std::vector<:string> str{ "123456789012345678", "abcd123456789012345678efgh", "abcdefbg", "12345678901234567X" }; std::string fmt{ "********" }; /* std::regex_replace: re , fmt */ for (auto tmp : str) { std::string ret = std::regex_replace(tmp, re, fmt); fprintf(stderr, "src: %s, dst: %s
", tmp.c_str(), ret.c_str()); } return 0; } int test_regex_replace2() { // reference: http://www.cplusplus.com/reference/regex/regex_replace/ std::string s("there is a subsequence in the string
"); std::regex e("\\b(sub)([^ ]*)"); // matches words beginning by "sub" // using string/c-string (3) version: std::cout << std::regex_replace(s, e, "sub-$2"); // using range/c-string (6) version: std::string result; std::regex_replace(std::back_inserter(result), s.begin(), s.end(), e, "$2"); std::cout << result; // with flags: std::cout << std::regex_replace(s, e, "$1 and $2", std::regex_constants::format_no_copy); std::cout << std::endl; return 0; }

GitHub:https://github.com/fengbingchun/Messy_Test