要約すると、正規表現パターンが文字列のセグメントを単語全体の変数名と間違えないようにするにはどうすればよいですか? 単語の境界を使用していても、より大きな単語の一部である文字を置き換えています\b
。
私がやろうとしていること:私は電卓に取り組んでいます。これには変数のリストがあり、式をパーサーに渡す前に、関数を呼び出して、ParseVars()
変数regex_search
マッチングのパターンを使用します。変数パターンに一致するすべてのトークンを取得したら、その文字列が実際に変数名のリストにあるかどうかを確認し、そうであれば、文字列を変数値に置き換えます。また、パーサーで計算が行われるたびに、 、 などの名前ans1
で定数を定義ans2
します。
問題は:a
という名前の変数が定義されていて、その値が であるとしましょう6
。(ちなみに、これらを a で追跡するmap<string,double> Vars;
とParseVars("ans1")
、結果の文字列は になります"ans1"
。また、 を使用してもParseVar()
、文字列ans1+ans2+9
は同じままです。文字列は に9+a
なり9+6
ます。したがって、これまでのところ、私の正規表現は期待どおりに機能します。
しかし、そうするとParseVars("ans1+a")
、結果の文字列は"6ns1+6"
. 変数を使用した場合にのみ正規表現の単語境界が失敗する理由について混乱しています。「a」は常に「ans1」で見つかりますが、「a」が文字列のどこかに単独である場合にのみ置き換えられます.
私が持っているもの:これが私の正規表現パターンです:\b([a-z][a-z0-9_]*)\b
これは単語全体にのみ一致するべきではありませんか? 単語境界は、'a' が文字列内のどこかで単独になるまで正常に機能します。多分それは私のParseVars()
機能です、ここにコードがあります:
map<string,double> Vars;
// Variables must be a whole word, start with a letter, and
// optionally have other letters, numbers, and underscores.
sregex VarPattern = sregex::compile("\\b([a-z][a-z0-9_]*)\\b");
string Calculator::ParseVars(string expr) {
if (Vars.empty()) return expr;
string newExpr = StrToLower(expr);
const sregex_iterator End;
// Loop through all possible variable matches
for (sregex_iterator i(expr.begin(), expr.end(), VarPattern); i != End; ++i) {
string name = (*i)[0];
// If it is a variable
if (Vars.find(name) != Vars.end()) {
int rPos = 0;
// Replace all occurrences of it
while ((rPos = newExpr.find(name, rPos)) != string::npos) {
newExpr.replace(
rPos, name.length(),
lexical_cast<string,double>(Vars[name])
);
}
}
}
return newExpr;
}
にa
等しいので6
、どうすれば望ましいのではなくans1+a
なるのを防ぐことができますか?6ns1+6
ans1+6