Regex-Word边界失败
Regex - Word boundaries failing
总结一下:如何防止regex模式将字符串段误认为是一个完整的单词变量名?即使我使用单词边界b
,它也会替换较大单词中的字母。
我想做的事:我正在做一个计算器。它有一个变量列表,在将表达式传递给解析器之前,我调用函数ParseVars()
,使用变量匹配模式来执行regex_search
。一旦它拥有了与我的变量模式匹配的所有标记,我就会检查该字符串是否真的在变量名列表中,如果是,我会用变量值替换该字符串。此外,每次在解析器中进行计算时,我都会定义一个名为ans1
、ans2
等的常量
问题是:假设我定义了一个变量,名为a
,其值为6
。(顺便说一句,我在map<string,double> Vars;
中跟踪这些。当我执行ParseVars("answers1")
时,得到的字符串是"answers1"
。同样对于ParseVar()
,字符串ans1+ans2+9
保持不变。字符串9+a
变为9+6
。因此,到目前为止,我的正则表达式按预期工作。
但是,如果我执行ParseVars("answers1+a")
,则结果字符串为"6ns1+6"
。我很困惑,为什么只有当我使用变量"a"时,正则表达式上的单词边界才会失败,"a"总是可以在"answers1"中找到,但只有当"a"在字符串中的其他地方单独存在时,它才会被替换。
我有什么:这是我的正则表达式模式:b([a-z][a-z0-9_]*)b
这不应该只匹配整个单词吗?单词boundary可以正常工作,直到字符串中的其他地方只有"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
?
好吧,我找到了解决方案。我在这里为遇到类似问题的人提供答案。
问题是,在正则表达式匹配后,我使用了一个基本的字符串替换,所以单词边界有效,只是字符串替换函数替换了字符串的每一个出现,而不考虑单词边界。我必须使用regex_replace()
,这是我最终得到的:
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()) {
sregex rgxName = sregex::compile("\b" + name + "\b");
// Replace all occurrences of it
newExpr = xpressive::regex_replace(
newExpr, rgxName,
lexical_cast<string,double>(Vars[name])
);
}
}
return newExpr;
}
- 如果没有malloc,链表实现将失败
- 模板参数替换失败,并且未完成隐式转换
- 具有默认模板参数的多态类的模板推导失败
- 视图中的参数推导失败:take_while
- 链接到自行创建的dll失败
- 带有特殊路径部分的"std::filesystem::weakly_canonical"失败
- GetShortPathName在网络驱动器上使用中文文件夹时失败
- gcc和c++17的过载解析失败
- 为什么使用 P/Invoke 调用 dll 时,某些计算机中的 LoadLibrary 失败?
- 在WSL:configure_file上对config_file的每次调用都失败:配置文件时出现问题
- 使用 GCC 卸载的 OpenMP 卸载失败,并出现"Ptx assembly aborted due to errors"
- 使用cmake从源代码构建MySQL连接器/C++失败(与以前的声明冲突)
- 链接阶段在Ubuntu上失败,但在MacOS上失败
- 从父数组测试用例构造二叉树失败
- std::当在256字节边界上写入整数时,流的奇怪行为
- LibGit2 SSH身份验证失败
- 如何让LLDB在成功时退出,在失败时等待
- VS2017,C++包含目录与附加包含目录,子文件夹包含失败-但为什么
- 生成MRPT库时cmake配置失败
- Regex-Word边界失败