c++ - C++ 正则表达式错误!方括号表达式不适用于 icase 标志
问题描述
// regex_replace example
#include <iostream>
#include <string>
#include <regex>
#include <iterator>
int main ()
{
std::string INPUT = "Replace_All_Characters_With_Anything";
std::string OUTEXP = "0";
std::regex expression("[A-Za-z]", std::regex_constants::icase);
std::cout << std::regex_replace(INPUT, expression, OUTEXP);
return 0;
}
这在这里有效:http ://cpp.sh/6gb5a 这在这里有效:https ://regexr.com/5bt9d
问题似乎归结为是否使用 icase 标志。A in All、C in Characters、W in With 等不会因为存在下划线而被替换。该错误似乎是,[]
仅当所述字符在不匹配之后没有出现时,才使用匹配事物。
似乎确实有一个快速解决方法,如果括号后面跟着一个 {1},那么它就可以工作。
例子:[A-Za-z]{1}
编译器:Microsoft Visual Studio Community 2019 / 版本 16.7.3 / c++17
也在 c++14 中测试过,同样的不良行为
解决方案
不确定这是否是回答的适当用途。但这是一个已知的错误,看起来这个错误已经知道几个月了。据我所知,没有 ETA 修复。
https://github.com/microsoft/STL/issues/993
看起来 RE2 是推荐的替代正则表达式库。
https://github.com/google/re2/
我将创建一个函数,而不是使用另一个库,该函数可用于拦截和更改正则表达式字符串作为临时修复。无论是否使用 icase 标志都应该有效。
测试代码:https ://rextester.com/LSNW3495
// add '{1}' after square bracket ranges unless there already is a quantifier or alternation such as '?' '*' '+' '{}'
std::string temporaryBugFix(std::string exp)
{
enum State
{
start,
skipNext,
lookForEndBracket,
foundEndBracket,
};
State state = start;
State prevState = start;
int p = -1;
std::vector<int> positionsToFix;
for (auto c : exp)
{
++p;
switch (state)
{
case start:
if (c == '\\')
{
prevState = state;
state = skipNext;
}
else if (c == '[')
state = lookForEndBracket;
continue;
case skipNext:
state = prevState;
continue;
case lookForEndBracket:
if (c == '\\')
{
prevState = state;
state = skipNext;
}
else if (c == ']')
{
state = foundEndBracket;
if (p + 1 == exp.length())
positionsToFix.push_back(p + 1);
}
continue;
case foundEndBracket:
if (c != '+' && c != '*' && c != '?')
positionsToFix.push_back(p);
state = start;
continue;
}
}
// check for valid curly brackets so we don't add an additional one
std::string s = exp;
std::smatch m;
std::regex e("\\{\\d+,?\\d*?\\}");
int offset = 0;
vector<int> validCurlyBracketPositions;
while (regex_search(s, m, e))
{
validCurlyBracketPositions.push_back(m.position(0) + offset);
offset += m.position(0) + m[0].length();
s = m.suffix();
}
// remove valid curly bracket positions from the fix vector
for (auto p : validCurlyBracketPositions)
positionsToFix.erase(std::remove(positionsToFix.begin(), positionsToFix.end(), p), positionsToFix.end());
// insert the fixes
for (int i = positionsToFix.size(); i--; )
exp.insert(positionsToFix[i], "{1}");
return exp;
}
推荐阅读
- asp.net-core - .NetCore Web API:在托管服务器中放置和删除时出现错误 403
- spring - 如何使用骆驼apache将xml转换为csv
- r - 为什么打印列表命令会更改 r 中的时区?
- python - Python - 每天从一个特定时间选择数据
- javascript - 需要有关允许澳大利亚手机和电话号码的正则表达式的帮助
- javascript - 何时使用 useState() 钩子的功能更新形式,例如。集合X(x=>x+1)
- amazon-s3 - Thanos 在 S3 中缺少指标
- python - 转换印度尼西亚日期时间 python
- visual-studio-code - VScode 打开三个名为“visual”、“studio”和“code”的空文件
- postgresql - Postgres - 仅按 UUID 查找