【问题标题】:Regex look behind in VS Code?正则表达式在 VS Code 中落后?
【发布时间】:2017-02-16 08:36:32
【问题描述】:

我正在开发 VS Code 中的语法扩展,但我在查看正则表达式模式时遇到了困难。给定以下字符串,我只想在 @fmt(

之前返回 cmp
@fmt(cmp,foo)

我在另一个编辑器中使用的匹配字符串是这样的:

(?<=[@|©](fmt)\()(\w+)

但是,这在 VS Code 中不起作用,当我进行正则表达式搜索时,它返回的错误是它不是有效的表达式。玩弄它,问题在于 字符,表示后面的样子。

搜索 VS Code 网站不会返回任何类型的正则表达式参考指南。搜索 Stack Overflow 得到了 this question,它指出 Visual Studio 有一个独特的正则表达式定义。不幸的是,该问题中给出的示例在 VS Code 中不起作用。

有人知道如何在 VS Code 中查看正则表达式吗?或者至少知道 VS Code 的正则表达式文档在哪里?

我担心这是不可能的,因为根据Stack Overflow reference,JavaScript 不支持后视。 another question 展示了如何在 JavaScript 函数中模仿外观,但我不知道是否可以使用用户定义的函数在 VS Code 中扩展语言。如果有人知道如何做到这一点,并且可以指出我的方向,那也是一个可以接受的解决方法。

【问题讨论】:

  • 托马斯,你在做什么?请解释你需要用@fmt(cmp,foo)做什么?最终结果是什么?查找并突出显示?那么您根本不需要后视,也不需要捕获组 - [@©]fmt\(\w+ 就足够了。
  • 用于语法高亮,我希望 @fmt 是一种颜色(函数),而 cmp 是另一种颜色(参数) . @ 符号后面有多个可能的字符串,这只是一个简化的示例。
  • 我确实有 @fmt 部分使用字符串 ([@|©|®]\w+) 工作。我只是对括号内的参数作为不同的颜色感到困惑,正如我在我在 Editpad Pro 语法着色中工作的问题中所说的那样。

标签: regex visual-studio-code regex-lookarounds vscode-extensions


【解决方案1】:

更新

Visual Studio Code v.1.31.0 及更高版本具有正则表达式后向支持,请参阅Wiktor's answer


Visual Studio 代码使用 ECMAScript 5 中指定的 JavaScript 正则表达式,它不支持向后查找 (https://github.com/Microsoft/vscode/issues/8635)。

如果您正在查找和替换,可以尝试以下解决方法(感谢 cyborgx37):

搜索表达式:

(lookbehind_expression_)text_to_replace

替换表达式:

$1replacement_text

给定输入:

lookbehind_expression_text_to_replace

输出将是:

lookbehind_expression_replacement_text

【讨论】:

【解决方案2】:

从 Visual Studio Code v.1.31.0 版本开始,您可以不受任何限制地使用infinite-width lookahead and lookbehind

查看证明:

还有另一个(使用(?&lt;=@fmt\([^()]*)\w+ 模式,注意后面的*):

Github [VSCode 1.31] ES2018 RegExp lookbehind assertions are now supported #68004 issue

由于迁移到 Electron 3.0,现在支持 RegExp 后向断言,因为它们从 Chromium 62Node 8.10 开始就受支持。 0,而 Electron 3.0 使用 Chromium 66Node 10.2.0,因此现在支持它们,但发行说明不要提及现在支持后向断言。

VS Code 开发人员 confirm that it is true 表示他们“忘记在发行说明中提及”。

【讨论】:

    【解决方案3】:

    在 VS Code 中向前看和向后看。下载一些现有的语言插件并查看它们的规则,以了解必须如何制定。这是我的 ANTLR 语法扩展的一部分:

    {
      "name": "meta.rule.parser.antlr",
      "begin": "[[:lower:]][[:alnum:]_]*(?=.*?:)",
      "beginCaptures": {
        "0": { "name": "entity.name.function.parser.antlr" }
      },
      "end": "(?<=;)",
      "patterns": [
        {
          "name": "variable.other",
          "match": "\\[.*?\\]"
        },
        {
          "name": "keyword.other.antlr",
          "match": "\\b(returns|locals)\\b"
        },
        {
          "name": "keyword.other.antlr",
          "match": "@\\w+"
        },
        {
          "name": "entity.other.rule.option",
          "match":" <.*?>"
        },
        {
          "name": "variable.other.antlr",
          "match": "\\w+\\s*="
        },
        {
          "name": "entity.name.tag.antlr",
          "match": "#.*"
        },
    
        { "include": "#comments" },
        { "include": "#strings" },
        { "include": "#lexer-rule-reference" },
        { "include": "#parser-rule-reference" },
        { "include": "#predicate" },
        { "include": "#action" },
        { "include": "#wildcard-regexp" },
        { "include": "#regexp-parts" },
        { "include": "#options-list" }
    
      ]
    }
    

    结束匹配使用回看模式。还请记住,您可以嵌套模式,即您可以为更大的结构(例如整个函数)定义开始/结束,然后将其部分与子模式匹配(并分配单独的样式)。这就是为什么您通常不需要向前/向后看的原因,因为您知道自己处于某个代码块中。

    对于您上面的模式:(\w+) 部分是否应该是后向模式的一部分?如果是这样,它应该在最后一个右括号之前。

    【讨论】:

    • 我尝试了(?&lt;=) 语法,仍然收到无效的正则表达式/无效组错误。 VS 代码似乎不支持反向引用:github.com/Microsoft/vscode/issues/8635
    • 你的lookarounds都是lookaheads,而不是lookbehinds。
    • (?= 是积极的前瞻,而(?&lt;= 是积极的后瞻。
    猜你喜欢
    • 2023-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-05
    • 1970-01-01
    • 2012-05-01
    • 2010-09-12
    • 2018-10-13
    相关资源
    最近更新 更多