【问题标题】:Regex in Sublime Text tmLanguage file doesn't use multilineSublime Text tmLanguage 文件中的正则表达式不使用多行
【发布时间】:2015-09-07 13:52:13
【问题描述】:

我正在尝试创建一个自定义语法语言文件,以突出显示并帮助在 Sublime Text 2 中创建新文档。我已经走了很远,但我遇到了一个关于 tmLanguage 文件中正则表达式搜索的特定问题。我只是希望能够在 YAML 文档中的多行上匹配正则表达式,然后将其转换为 PList 以在 Sublime Text 中作为包使用。它不会工作。

This 是我的正则表达式:

/(foo[^.#]*bar)/

这就是它在 tmLanguage YAML 文档中的外观:

patterns:
- include: '#test'

repository:
  test:
    comment: Tester pattern
    name: constant.numeric.xdoc
    match: (foo[^.#]*bar)

如果我将此 YAML 构建为 tmLanguage 文件并将其用作 Sublime Text 中的包,我会创建一个使用此自定义语法的文档,尝试一下,会发生以下情况:

这将匹配:

foo 12345 bar

这将不匹配:

foo
12345
bar

a Regex tester 中,它们应该并且都将匹配,但在我的 tmLanguage 文件中它不起作用。

我也已经尝试在 tmLanguage 文件中为我的正则表达式添加修饰符,但以下内容要么不起作用,要么完全破坏了文档:

match: (/foo[^.#]*bar/gm)
match: /(/foo[^.#]*bar/)/gm
match: /foo[^.#]*bar/gm
match: foo[^.#]*bar

注意:我的 Regex 规则在测试器中有效,此问题仅出现在 Sublime Text 2 中的 tmLanguage 文件中。

非常感谢任何帮助。

编辑:我使用匹配而不是开始/结束子句的原因是因为我想使用捕获组给它们不同的名称。如果有人有一个带有 begin 和 end 子句的解决方案,您仍然可以以不同的方式命名 'foo'、'12345' 和 'bar',我也可以。

【问题讨论】:

  • 对不起,我在测试之前回答了:)我要删除,稍后再回答。
  • 试试 name: my.new.variable // contentName: string.other // begin: 'foo' // end: 'bar' // patterns: // - include: $self // - name: support.keyword // match: [^.#] 之类的(请重新格式化,因为 cmets 不允许换行)。
  • 你有时间检查吗?我相信你需要检查this page for more help
  • 我知道 begin 和 end 子句,但我需要对 '#' 和 '.' 之间的不同部分进行编号。人物。这就是我使用 Regex 的原因,因为我可以使用捕获组来命名它们。

标签: regex sublimetext2


【解决方案1】:

我发现这是不可能的。这是直接来自TextMate Manual,是Sublime Text基于的文本编辑器。

12.2 语言规则

<...>

注意正则表达式只匹配一个 文档的一行。这意味着不可能使用 匹配多行的模式。其原因是技术性的: 能够在任意行重新启动解析器并且必须 仅重新解析受编辑影响的最少行数。多数情况 在这种情况下,可以使用开始/结束模型来克服这个问题 限制。

我的情况是开始/结束模型无法克服限制的少数情况之一。不幸。

【讨论】:

  • 这令人失望。最近遇到了同样的问题(在 vscode 中)。你有没有找到任何替代方案?
【解决方案2】:

很久没问了,但你确定不能使用 begin/end 吗?在我更好地掌握语法/逻辑之前,我在开始/结束方面遇到了类似的问题。这是我正在做的 json tmLanguage 文件的一个粗略示例(不知道正确的 YAML 语法)。

"repository": {

"foobar": {
    "begin": "foo(?=[^.#]*)", // not sure about what's needed for your circumstance. the lookahead probably only covers the foo line
    "end": "bar",
    "beginCaptures": {
        "0": {
            "name": "foo"
        }
    },
    "endCaptures": {
        "0": {
            "name": "bar"
        }
    },
    "patterns": [
        {"include": "#test-after-foobarmet"}
    ]
},
"test-after-foobarmet": {
    "comment": "this can apply to many lines before next bar so you may need more testing",
    "comment2": "you could continue to have captures here that go to another deeper level...",
    "name": "constant.numeric.xdoc",
    "match": "anyOtherRegexNeeded?"
}

}

我没有关注你的

“我需要对'#'和'.'之间的不同部分进行编号 字符。”

,但是如果需要在 foo bar 之间命名不同的组,您应该能够在 test-after-foobarmet 中进行更多捕获的测试。

有很好的explanation of TextMate Grammar here。可能仍会遇到一些错误,但在我对该主题一无所知时以对我有帮助的方式进行解释。

【讨论】:

  • 天啊,这是几年前的事了……不过我确实记得这个问题。假设您要查找多行关键字“begin-tag-abc.content.end-tag”。我可以在语言文件中使用 begin 和 end 子句来执行此操作,但如果“abc”数据段可能包含“abc”以外的内容,我将无法提取它。
  • 在您制作的示例中,假设“foo”开始捕获也可能是“fao”或“fbo”或“fco”,我该如何检索这些数据?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-22
  • 2017-07-24
  • 1970-01-01
  • 2014-11-25
  • 1970-01-01
相关资源
最近更新 更多