【问题标题】:Regex pattern to produce appropriate escape character behavior正则表达式模式产生适当的转义字符行为
【发布时间】:2018-11-20 23:46:58
【问题描述】:

我正在为语法高亮创建一个 Sublime Text 3 语言定义。该语言是一种简单的“表达语言”(与 Java 无关),用于在显示面板上显示来自媒体库的信息。语法高亮的目的是明确将在面板上显示的内容。

因此,我想准确地解释转义字符序列在解释和显示在显示面板上时的样子。转义字符是一个正斜杠,如果你想显示一个正斜杠,你必须用另一个转义它。因此,一系列正斜杠将导致面板上显示每隔一个正斜杠。此外,如果在正斜杠之后有特殊字符,它将被转义 - 但如果在两个(或四个,或六个......)正斜杠之后放置一个特殊字符,它将不会被转义,因为转义字符会相互抵消。

我想要实现的突出显示(例如特殊字符's')如下:

我必须通过以 YAML 格式提供 Sublime Text 正则表达式来实现这一点,因此解决方案必须是纯正则表达式。

这可能吗?如果是这样,我该如何实现?

【问题讨论】:

  • 你不想要奇数个斜线。您希望成对的斜线变成文字斜线,然后单斜线是转义字符。

标签: regex yaml sublimetext3 syntax-highlighting


【解决方案1】:

查找奇数个斜线并不是特别有用。这是一个删除斜线的解析练习。如果斜线后面跟着另一个斜线,则为文字斜线,否则为后面的任何内容。

但是等一下,那里没有区别 - 无论后面的 char 是什么,它都是文字,所以...

使用正则表达式 /(.) 匹配所有“斜杠-anychar”对,并替换为捕获的字符。

在java中:

str = str.replaceAll("/(.)", "$1");

在python中:

str = re.sub('/(.)', '$1', str)

在 perl 中:

$str =~ s/\/(.)/$1/

【讨论】:

  • 要是这么简单就好了!我在 YAML 中,所以我需要一个纯粹的正则表达式解决方案。我应该添加一个 YAML 标签。我现在就这么做。
  • @dan YAML 与您的问题有什么关系?你不能在 in YAML 中“做”任何事情——它是纯数据。请在您的问题中详细说明您要做什么。
  • 也许说我“在 YAML 中”令人困惑,但我的意思是我没有编写任何东西 - 我正在向程序提供指令,这些指令采用 YAML 格式。指令包含正则表达式,如果我输入正确的正则表达式,程序将表现出我要求的行为。该程序是 Sublime Text 3,其行为是语法高亮。所以我只需要一个纯正则表达式解决方案来挑选出我的问题中描述的模式。
【解决方案2】:

如果没有关于您当前拥有的语法结构的更多信息,很难确定,但我认为您在这里寻找的只是一个简单的单个 match 构造,它与文字字符 / 匹配后跟任何允许作为转义字符的字符,在您的示例中是字符 s 和字符 /

您可能会认为您尝试创建的正则表达式需要找到包含任何转义序列组合的最大可能匹配项。但是,您提供的 match 规则会根据需要多次使用以使用输入,因此它们一次只需要匹配单个语法结构。

一个简单的例子就是下面的最小语法。前两个 match 结构仅用于下图中的示例;他们实现了行注释并在未转义时将“s”标记为特殊,以便在这种情况下更清楚。

第三条规则是匹配有效转义序列的内容,即/ 后跟另一个/(文字/)或s(文字s)。

最后一条规则是可选的,它匹配/ 字符后跟任何不是有效转义字符(包括后面没有任何东西),并将其标记为invalid,以提示用户他们'我做了一些傻事。

在这里,我添加了一个空格字符作为可能有效的转义符,以进行无效转义检测,这样在裸 / 之后的尾随空格也不会获得 invalid 范围。没有它,语法假定您试图引用空格字符。

%YAML 1.2
---
scope: source.example
contexts:
  main:
    # A simple single-line comment scope capture for nice output
    - match: '(#).*\n?'
      captures:
        0: comment.line.number-sign.example
        1: punctuation.definition.comment.example
    # Just so we can apply a color to the letter s to know when it's "special"
    - match: 's'
      scope: entity.name.special
    # The set of things that can be valid escapes
    - match: '/[s/]'
      scope: constant.character.escape.example
    # If only s and / are valid escapes, make other escapes invalid, including
    # using a bare / with nothing following it.
    - match: '/[^s/ ]?'
      scope: invalid.illegal.escape.example

在一个简单的测试中,这个语法的结果是:

【讨论】:

  • 谢谢。我可能会在紧要关头使用这个解决方案......我现在可以看到我没有完全解释自己,虽然(我实际上是 Stack Overflow 的新手,Sublime Text 的新手,YAML 的新手和 Regex 的新手,所以我通常有点困惑)。我已经修改了我的问题,以明确说明我想要实现的目标 - 我认为这应该清楚 - 你介意看一下吗?
  • 为了清楚起见,您是否期望当您在文件中输入一些文本时,语法高亮也会修改文本以删除一些/ 字符等?
  • 没有。没有修改文本,只是如图所示突出显示,以指示将被显示的表达式解释器删除的内容。
  • 您看到灰色斜线是多么容易被忽略,因此更容易看到解释器完成工作后显示的样子?
【解决方案3】:

好吧,所以对于它的价值,我想通了。这个:

%YAML 1.2
---

file_extensions:
  - example

  scope: source.example

  contexts:
    main:
    # special color setup #

    - match: s
      scope: green


    # desired behaviour #

      - match: '(/)(.)?'
        captures:
          1: grey
          2: white

给你这个:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-05
    • 1970-01-01
    • 2019-11-21
    • 2010-12-22
    • 2010-09-21
    • 2020-07-24
    相关资源
    最近更新 更多