如何简化C ++布尔比较

时间:2015-07-12 00:39:01

标签: c++ qt

我正试图找到一种方法来简化布尔值的比较情况。目前,只有三个(如下所示),但我即将添加第四个选项,这将变得非常乏味。

bracketFirstIndex = message.indexOf('[');
mentionFirstIndex = message.indexOf('@');
urlFirstIndex = message.indexOf(urlStarter);

bool startsWithBracket = (bracketFirstIndex != -1);
bool startsWithAtSymbol = (mentionFirstIndex != -1);
bool startsWithUrl = (urlFirstIndex != -1);     

if (!startsWithBracket)
{
    if (!startsWithAtSymbol)
    {
        if (!startsWithUrl)
        {
            // No brackets, mentions, or urls. Send message as normal
            cursor.insertText(message);
            break;
        }
        else
        {
            // There's a URL, lets begin!
            index = urlFirstIndex;
        }
    }
    else
    {
        if (!startsWithUrl)
        {
            // There's an @ symbol, lets begin!
            index = mentionFirstIndex;
        }
        else
        {
            // There's both an @ symbol and URL, pick the first one... lets begin!
            index = std::min(urlFirstIndex, mentionFirstIndex);
        }
    }
}
else
{
    if (!startsWithAtSymbol) 
    {
        // There's a [, look down!
        index = bracketFirstIndex;
    }
    else
    {
        // There's both a [ and @, pick the first one... look down!
        index = std::min(bracketFirstIndex, mentionFirstIndex);
    }

    if (startsWithUrl)
    {
        // If there's a URL, pick the first one... then lets begin!
        // Otherwise, just "lets begin!"
        index = std::min(index, urlFirstIndex);
    }
}

是否有更好/更简单的方法来比较几个布尔值,或者我是否坚持这种格式,我应该尝试在适当的位置挤入第4个选项?

2 个答案:

答案 0 :(得分:3)

某种类型的文本处理相当常见,对于那些,您应该强烈考虑使用现有的库。例如,如果您正在处理的文本使用markdown语法,请考虑使用现有库将markdown解析为结构化格式以供您解释。

如果这是完全自定义解析,那么有几个选项:

  • 用于非常简单的文本处理(就像预期的单个字符串一样) 如果是少数格式之一或包含预期格式的一个子文本,请使用regular expressions。在C ++中,RE2库为匹配和提取正则表达式提供了非常强大的支持。

  • 对于更复杂的文本处理,例如跨越多行或具有各种内容/语法的数据,请考虑使用现有的词法分析器和解析器生成器。 FlexBison是常用工具(一起使用),用于根据语法自动生成用于解析文本的逻辑。

  • 你可以像现在一样手工编写自己的解析逻辑。

如果采用后一种方法,有几种简化方法:

  1. 分开" lexing" (将输入分解为令牌)和"解析" (将一系列令牌解释)分为不同的阶段。

  2. 定义一个"令牌" class和相应的层次结构,表示可以出现在语法中的符号类型(如RawText,Keyword,AtMention等)

  3. 创建一个或多个枚举,表示解析逻辑可以处于的状态。

  4. 将lexing和解析逻辑实现为状态机,在给定当前状态和下一个标记或字母的情况下转换状态。构建从(状态,令牌类型)到next_state或从(状态,令牌类型)到handler_function的映射可以帮助您简化结构。

答案 1 :(得分:0)

由于您只切换起始字母,用例:

enum State { Start1, Start2, Start3, Start4};
State state;
if (startswithbracket) {
   state = Start1;
} else {
.
.
.
}

switch (state) {
   case Start1:
      dosomething;
      break;
   case Start2:
      .
      .
      .
 }

有关切换语法和用例的更多信息,请参见here