【问题标题】:Regular expression match only if subpattern doesn't match仅当子模式不匹配时,正则表达式才匹配
【发布时间】:2009-03-25 12:34:34
【问题描述】:

我正在尝试匹配 C 风格的 cmets 形成一个文件,但前提是注释不以 @ 引入的某些标签开头

例如来自

/* some comment to match */
/* another comment.
this should match also */
/*@special shouldn't match*/

这可能只使用正则表达式吗?

我正在尝试使用正则表达式的 JavaScript 实现。

【问题讨论】:

    标签: javascript regex


    【解决方案1】:
    /\*\s*(?!@)(?:(?!\*/).)*\*/
    

    分解为:

    /\* // "/*" \s* // 可选空格 (?!@) // 后面没有“@” (?: // 不捕获... (?!\*/)。 // ...任何不是“*/”的东西 )* // 但尽可能频繁地匹配它 \*/ // "*/"

    在“global”和“dotall”模式下使用(例如,点也应该匹配新行)

    通常的警告词: 与所有使用正则表达式执行的解析作业一样,这将在嵌套模式和中断输入时失败。

    emk points out a nice example 的(否则有效)输入将导致此表达式中断。这无济于事,正则表达式不适用于解析。如果您确信这样的事情永远不会在您的输入中发生,那么正则表达式可能仍然适合您。

    【讨论】:

    • 只是为了迂腐,\s*(?!@).?并不意味着你认为它意味着什么,而是一个 0 宽度的负前瞻。这意味着一旦您匹配了尽可能多的空格 (\s*),仅当下一个字符不是 @ 时才继续匹配。这 。?是不必要的。
    • 只是为了迂腐,你认为我怎么可能在不知道它是什么的情况下写一个否定的前瞻? ;-) 你对“.?”的看法是对的不过,这是不必要的。我删除了它。
    【解决方案2】:

    你可以这样开始:

    /\*[^@]
    

    但一般来说,您不会注意将 C 风格的 cmets 与正则表达式匹配,因为存在令人讨厌的极端情况。考虑:

    "foo\" /* " " */ "
    

    该代码中没有注释(这是两个字符串文字的编译时连接),但是如果没有真正的解析器,您将不会有太多的运气来解析它。 (从技术上讲,您可以使用正则表达式,因为您只需要一个简单的有限状态机。但这是一个非常恶心的正则表达式。)

    【讨论】:

    • +1 用于指出有风险的部分。不过,我认为您不能使用正则表达式来成功解析类似 C 的语言。即使是一个非常丑陋的人。
    • 即使您无法使用正则表达式解析任意 C 代码,但您实际上可以剥离 cmets。我之前实际上已经编写了一个状态机来执行此操作,并且任何此类状态机都可以转换为正则表达式。但我不认为我可以在没有大量头骨汗水的情况下手工构建它。
    【解决方案3】:

    使用负前瞻

    【讨论】:

      猜你喜欢
      • 2011-10-25
      • 2019-09-05
      • 1970-01-01
      • 2017-10-16
      • 1970-01-01
      • 2019-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多