JS正規表現ではsymbols^
および$
指定文字列の開始と終了。そして/m
修飾子(マルチラインモード)一致します行の開始と終了-CR/LFの前後の位置。
しかし std :: regex /ECMAscriptモードのシンボルでは^
および$
match 行の開始と終了常に。
Std :: regexに文字列の開始と終了マッチポイントを定義する方法はありますか?言い換えれば、JavaScriptマルチラインモードをサポートするには...
デフォルトでは、ECMAscriptモードはすでに^
を入力の始まりとの両方の行の始まり、および$
として扱います。入力の終わりとの両方の行の終わりとして。入力の開始時または終了時にonlyに一致させる方法はありませんが、一致させることはできますonly行頭または行末:
std::regex_match
、 std::regex_search
、または std::regex_replace
を呼び出す場合、-型の引数があります。 std::regex_constants::match_flag_type
デフォルトでstd::regex_constants::match_default
になります。
^
が行頭のみに一致することを指定するには、std::regex_constants::match_not_bol
を指定します$
が行末のみに一致することを指定するには、std::regex_constants::match_not_eol
を指定しますstd::regex_constants::match_not_bol | std::regex_constants::match_not_eol
)^
を使用せずに、std::regex_constants::match_not_bol
の存在に関係なく、std::regex_constants::match_continuous
を指定することで暗示できることに注意してください。これは、 ECMAScript文法ドキュメント on cppreference.com で詳しく説明されています。これは、一般的にcplusplus.comよりも強くお勧めします。
警告:MSVC、Clang + libc ++、およびClang + libstdc ++でテストしましたが、現時点ではMSVCのみが正しい動作をしています。
TL; DR
^
と$
はすでに行の開始と終了に一致していますstd::regex_constants::multiline
オプション^
と一致させ、文字列の終了を$
と一致させるだけであり、動作を再定義することはできません。MSVC以外のC++ 17より前のすべてのstd::regex
実装では、^
と$
は文字列の最初と最後に一致します。線ではありません。 このデモ を参照してください。"1\n2\n3"
で^\d+$
正規表現と一致するものが見つかりません。交替を追加すると(以下を参照)、 つの一致があります 。
ただし、MSVCおよびC++ 17では、^
および$
が行の開始/終了と一致する場合があります。
C++ 17
std::regex_constants::multiline
オプションを使用します。
MSVCコンパイラ
VisualStudioのC++プロジェクトでは、次のようになります。
std::regex r("^\\d+$");
std::string st("1\n2\n3");
for (std::sregex_iterator i = std::sregex_iterator(st.begin(), st.end(), r);
i != std::sregex_iterator();
++i)
{
std::smatch m = *i;
std::cout << "Match value: " << m.str() << " at Position " << m.position() << '\n';
}
出力します
Match value: 1 at Position 0
Match value: 2 at Position 2
Match value: 3 at Position 4
C++コンパイラ間で機能する回避策
std::regex
には、すべてのコンパイラでアンカーを行の開始/終了に一致させるためのuniversalオプションはありません。交互にエミュレートする必要があります。
^ -> (^|\n)
$ -> (?=\n|$)
$
は(?=\n|$)
((?=\r?\n|\r|$)
などの行末記号または記号シーケンスを追加できます)で完全に「エミュレート」できますが、^
ではできません。 100%の回避策を見つけてください。
後読みサポートがないため、後読みサポートよりも頻繁にキャプチャグループを使用するなど、(^|\n)
のために、正規表現パターンの他の部分を調整する必要がある場合があります。
次のコードスニペットは、[a-z]で始まり、0または1ドット、0以上のa-z文字、「@ gmail.com」で終わるメールアドレスと一致します。私はそれをテストしました。
string reg = "^[a-z]+\\.*[a-z]*@gmail\\.com$";
regex reg1(reg, regex_constants::icase);
reg1(regex_str, regex_constants::icase);
string email;
cin>>email;
if (regex_search(email, reg1))
文字列の先頭で一致するが改行の後では一致しないPerl/Python/PCRE _\A
_を、「行の先頭に一致する」として英語に変換されるJavascript正規表現^(?<!(.|\n)])
でエミュレートできます。前の文字がない」。
_\z
_を使用して、文字列の終わりでのみ一致するPerl/Python/PCRE _(?!(.|\n))$
_をエミュレートできます。 _\Z
_の効果を得るには、文字列の終わりでのみ一致しますが、その文字列の終わりの直前に1つの改行を許可するには、オプションの改行\n?(?!(.|\n))$
を追加するだけです。