【问题标题】:Most efficient method to parse small, specific arguments解析小而具体的参数的最有效方法
【发布时间】:2010-12-26 08:12:39
【问题描述】:

我有一个命令行应用程序需要支持以下品牌的参数:

  1. 全部:返回所有内容
  2. 搜索:返回第一个匹配项进行搜索
  3. all*search:返回匹配搜索的所有内容
  4. X*search:返回前 X 个匹配项进行搜索
  5. search#Y:返回第 Y 个匹配项进行搜索

search 可以是单个关键字,也可以是空格分隔的关键字列表,由单引号分隔。关键字是一个或多个字母和数字的序列 - 仅此而已。

几个例子可能是:

  1. 2*foo
  2. 栏#8
  3. 所有*'foo bar'

这听起来很复杂,以至于想到了 flex/bison - 但是应用程序可能需要非常频繁地解析这样的字符串,我觉得(因为不涉及计数)一个成熟的解析器会完全产生开销太大。

你会推荐什么?一长串的字符串操作?一些强大的子模式捕获正则表达式? “真正的”解析器实际上有一个合理的论据吗?

请注意,此伪语法的语法不会更改,因此如果代码变得难以维护,我不会哭泣。这一切都在 C++ 中,如果有什么不同的话。

谢谢!

【问题讨论】:

  • 我会说“这听起来简单足以手动编码。”在没有 lex/yacc/regexp 的情况下,我做了比这更复杂的解析。
  • 我喜欢你的观点——事实上,我已经退后一步,重新审视了这个问题,现在看到了普通字符串操作可以轻松解决这个问题。

标签: c++ regex parsing command-line string


【解决方案1】:

我不会为此推荐一个完整的 lex/yacc 解析器。你所描述的可以适合一个简单的正则表达式:

 ((all|[0-9]+)\*)?('[A-Za-z0-9\t ]*'|[A-Za-z0-9]+)(#[0-9]+)?

如果您有支持捕获的正则表达式引擎,则可以轻松提取所需的单条信息。 (很可能在捕获 1,3 和 4 中)。

如果我明白你的意思,你可能会想要检查捕获 1 和捕获 4 是否不是同时为非空的。

如果您需要进一步拆分搜索词,您可以在后续步骤中进行,解析捕获 3。

即使没有正则表达式,我也会手写一个函数。它会比处理 lex/yacc 更简单,我想你可以组合一些比正则表达式更有效的东西。

【讨论】:

  • 这很好地证实了我的想法(使用正则表达式)。同意我可以编写原始字符串操作以比将 PCRE 投入竞争更有效地满足要求 - 但经过反思,那里的净收益可能不值得我花时间调试。感谢您的洞察力!
【解决方案2】:

答案主要取决于您想要进行多少编码和想要依赖多少库之间的平衡 - 如果您的应用程序可以依赖其他库,您可以使用许多正则表达式库中的任何一个 - 例如所有 Linux/Unix 风格的 POSIX 正则表达式。

如果您只想要那些特定的语法,我会使用字符串标记器 (strtok) - 在 '*' 上拆分并在 '#' 上拆分 - 然后处理每种情况。

【讨论】:

  • 虽然我决定不使用 strtok,但我确实设法找到了一个没有正则表达式库的相当简单的解决方案。
【解决方案3】:

在这种情况下,strtok 方法会更好,因为要解析的命令数量很少。

【讨论】:

    猜你喜欢
    • 2010-10-11
    • 2018-10-08
    • 2011-08-29
    • 2018-10-27
    • 2014-06-02
    • 1970-01-01
    • 1970-01-01
    • 2013-09-17
    • 2021-08-20
    相关资源
    最近更新 更多