代码之家  ›  专栏  ›  技术社区  ›  Max Leske Thomas Shelby

只使用一个表达式匹配第一个匹配的更改版本?

  •  1
  • Max Leske Thomas Shelby  · 技术社区  · 16 年前

    我正在为alex gorbatchev的语法highlighter编写一个刷子,以突出显示smalltalk代码。现在,考虑下面的smalltalk代码:

    aCollection do: [ :each | each shout ]
    

    我想找到块参数:“每个”然后在每次它发生之后匹配“每个”(为了简单起见,让我们假设每次发生都不只是在括号内)。 注意,参数可以有任何名称,例如“:myarg”。

    我尝试匹配“:每个”:

    \:([\d\w]+)
    

    这似乎奏效了。问题是我要匹配“每个”的出现。我认为这样的事情可以奏效:

    \:([\d\w]+)|\1
    

    但是,交替的右侧似乎被视为一个独立的表达式,因此反向引用不起作用。

    是否有可能用一个单一的表达来实现我想要的?或者我必须在第二个表达式中使用backreference(通过另一个函数调用)?

    2 回复  |  直到 11 年前
        1
  •  0
  •   Tim Pietzcker    16 年前

    能够 使用支持可变长度的lookbehind的语言(只有.NET框架语言支持Afaik,Perl6可能支持)。在那里,如果一个词匹配,你可以加亮显示。 (?<=:(\w+)\b.*)\1 . 但javascript根本不支持lookback。

    但是无论如何,这个regex会非常低效(我刚刚在regexbuddy中检查了一个简单的例子,而且regex引擎需要对文档中几乎每个字符执行60多个步骤来决定匹配和不匹配),因此如果您想使用它来突出显示代码,这不是一个好主意。

    我建议你使用你提到的两步方法:第一场比赛 :(\w+)\b (为安全起见插入了单词边界, \d 隐含在 \w ,然后对匹配结果执行文本搜索 \1 .

        2
  •  0
  •   Jens    16 年前

    我相信regex引擎在匹配之间存储的唯一东西就是最后一个匹配的位置。因此,在查找下一个匹配项时,不能使用以前匹配项的后向引用。

    所以,不,我不认为这是可能的。