首页 > 解决方案 > Autosar 标准编译方式使用正则表达式

问题描述

我需要解析类似 URI 的字符串。此 URI 特定于项目并对应于“ scheme://path/to/file”,从文件系统的角度来看,路径应该是语法正确的文件路径。为此目的std::regex与 pattern 一起使用R"(^(r[o|w])\:\/\/(((?!\$|\~|\.{2,}|\/$).)+)$)"

它工作正常,但代码分析器认为它不兼容,因为$字符不属于 C++ 语言标准基本源字符集:

AUTOSAR C++14 A2-3-1(必需) 只有在 C++ 语言标准基本源字符集中指定的字符才能在源代码中使用。

此规则的例外情况(根据Autosar 指南):

允许在宽字符串的文本和 UTF-8 编码的字符串文字中使用其他字符。

wchar_t被其他规则禁止,尽管它可以使用UTF-8 string(但它在代码中看起来很丑陋且不可读,我担心它也不安全)。

有人可以帮助我解决问题,或者std::regex这不是最好的解决方案,那么什么会更好?

使用 UTF-8 字符串文字还有其他缺点吗?

PS我需要$确定(在解析阶段)路径不是目录,并且它不包含任何/../, ~, $,所以我不能跳过它。

标签: c++regexc++11standards-complianceautosar

解决方案


我觉得为了让分析器满意而使代码变得更糟会适得其反,而且很可能违反了指南的精神,所以我故意忽略了解决问题的方法,这些方法涉及以复杂的方式构建正则表达式字符串,因为你所做的是构建这样一个正则表达式字符串的最佳方法。

有人可以帮助我解决方法或 std::regex 这里不是最好的解决方案,那么什么会更好?

选项 A:编写一个简单的验证函数:

我真的很惊讶如此严格的指导方针甚至首先允许使用正则表达式。众所周知,它们很难审计、调试和维护。

您可以使用实际代码轻松表达相同的逻辑,这不仅可以满足分析员的要求,而且更符合指南的精神。最重要的是,它会编译得更快,并且可能运行得更快。

基于对您的正则表达式的粗略阅读,这些粗略的东西。(请不要在没有通过一系列测试的情况下使用它,我肯定没有):

bool check_and_remove_path_prefix(std::string_view& path) {
  constexpr std::array<std::string_view, 2> valid_prefixes = { 
    R"(ro://)", 
    R"(rw://)"
  };

  for(auto p: valid_prefixes) {
    if(path.starts_with(p)) {
      path.remove_prefix(p.size());
      return true;
    }
  }
  return false;
}

bool is_valid_path_elem_char(char c) {
  // This matches your regex, but is probably wrong, as it will accept a bunch of control characters.
  // N.B. \x24 is the dollar sign character
  return c != '~' && c != '\x24' && c != '\r' && c != '\n';
}
 
bool is_valid_path(std::string_view path) {
  if(!check_and_remove_path_prefix(path)) { return false; }

  char prev_c = '\0';
  bool current_segment_empty = true;
  for(char c : path) {
    // Disallow two or more consecutive periods
    if( c == '.' && prev_c == '.') { return false; }

    // Disallow empty segments
    if(c == '/') {
      if(current_segment_empty) { return false; }
      current_segment_empty = true;
    }
    else {
      if(!is_valid_path_elem_char(c)) { return false; }
      current_segment_empty = false;
    }
    
    prev_c = c;
  }

  return !current_segment_empty;
}

选项 B:不要打扰支票

从我们的角度来看,很难确定该选项是否适合您,但对于每个意图和目的,格式错误的路径和不指向有效文件的格式正确的路径之间的区别是没有实际意义。

所以只要使用路径,就好像它是有效的一样,你应该处理由于路径格式错误而导致的错误。


推荐阅读