我的字符串看起来像这样
macd_at([{1036}].CLOSE,10,10,10).UPPER
在这个字符串中,我试图匹配这个正则表达式
([a-zA-Z][a-zA-Z0-9_]*_(at|AT)\((((\[\{[0-9]+\}\](\.(OPEN|CLOSE|LOW|HIGH))?)|[1-9][0-9]*\.?[0-9]*|(TRUE|FALSE)|\"[^"]*\"),)*((\[\{[0-9]+\}\](\.(OPEN|CLOSE|LOW|HIGH))?)|[1-9][0-9]*\.?[0-9]*|(TRUE|FALSE)|\"[^"]*\")\)(\.(VALUE|UPPER|LOWER|PRICE))?)
在检查正则表达式的在线网站中,这是匹配的,但是当我调用std :: regex_search时,它不起作用。 VS C ++库中是否存在一些错误?
当我更改字符串
时macd_at([{1036}],10,10,10).UPPER
std :: regex_search正在运作。 是否有一些限制正则表达式的复杂性。
PS:正在使用正则表达式构建过程(为了更容易寻找正则表达式):
const std::string NUMBER_REGEX_PATERN = "[1-9][0-9]*\\.?[0-9]*";
const std::string OPERATOR_REGEX_PATERN = "(\\*|/|-|\\+)";
const std::string SYMBOL_REGEX_PATERN = "\\[\\{[0-9]+\\}\\]";
const std::string SYMBOL_SUFFIX_REGEX_PATERN = "(\\.(OPEN|CLOSE|LOW|HIGH))";
const std::string SYMBOL_WHOLE_REGEX_PATERN = "(" + SYMBOL_REGEX_PATERN + SYMBOL_SUFFIX_REGEX_PATERN + "?)";
const std::string STRING_REGEX_PATERN = "\\\"[^\"]*\\\"";
const std::string BOOLIAN_REGEX_PATERN = "(TRUE|FALSE)";
const std::string LITERAL_REGEX_PATERN = "(" + SYMBOL_WHOLE_REGEX_PATERN + "|" + NUMBER_REGEX_PATERN + "|" + BOOLIAN_REGEX_PATERN +"|" + STRING_REGEX_PATERN + ")";
const std::string STUDY_NAME_REGEX_PATERN = "[a-zA-Z][a-zA-Z0-9_]*_(at|AT)";
const std::string STUDY_SUFFIX_REGEX_PATERN = "(\\.(VALUE|UPPER|LOWER|PRICE))";
const std::string WHOLE_STUDY_REGEX_PATERN = STUDY_NAME_REGEX_PATERN + "\\((" +LITERAL_REGEX_PATERN + ",)*"+ LITERAL_REGEX_PATERN + "\\)";
const std::string WHOLE_STUDY_WITH_SUFIX_REGEX_PATERN = "(" + WHOLE_STUDY_REGEX_PATERN + STUDY_SUFFIX_REGEX_PATERN + "?)";
答案 0 :(得分:1)
看到模式的复杂性,过度回溯可能是一个问题。可以减少回溯的一点是你的倒数第二个构建块。尝试更改
...(" +LITERAL_REGEX_PATERN + ",)*"+ LITERAL_REGEX_PATERN...
到
...LITERAL_REGEX_PATERN + "(" +LITERAL_REGEX_PATERN + ",)*"...
这是unrolling-the-loop技术的简化形式,可以减少很多回溯量。请注意,两种模式都完全匹配相同的字符串。
要优化的另一点:
如果您不需要所有捕获组(我怀疑您需要它们,因为它们中的一些会在重复中被覆盖),请将它们转换为非捕获组。 E.g。
(?:\\.(?:OPEN|CLOSE|LOW|HIGH))
特别是与回溯相结合,不必要的捕获会变得相当昂贵。