使用正则表达式从Forth源代码中删除注释

时间:2016-09-01 09:18:51

标签: regex go comments tokenize

我试图匹配括号之间的所有内容,包括以非贪婪的方式括起来的括号。开括号前后的空格(或开括号前的一行的开头)和右括号前后的空格应该有一个空格。请采用以下文字:

 ( )
  ( This is a comment )
    1 2 +
\ a
: square dup * ;
( foo bar 
baz )
(quux)
( ( )
(
( )

第一行应匹配,第二行包括其内容应匹配,第二行不应匹配(或引发错误),最后一行应匹配。两条线foo bar baz应匹配,但(quux)不应该,因为它在括号前后不包含空格。内部带有额外开口括号的行应匹配。

我尝试了几个常规正则表达式来匹配括号内的内容,但没有太大的成功。正则表达式引擎是Go的。

3 个答案:

答案 0 :(得分:1)

HANDLE newHandle = ReOpenFile(origHandle,
                             FILE_GENERIC_READ | FILE_GENERIC_WRITE,
                             FILE_SHARE_READ, 0);

游乐场:https://play.golang.org/p/t93tc_hWAG

答案 1 :(得分:1)

正则表达式“不能计数”(这是过度简化的,但请耐心等待),因此无法在无限量的括号嵌套上进行匹配。我想你最关心的是在这种情况下只匹配一个级别,所以你需要使用类似的东西:

foo := regexp.MustCompile(`^ *\( ([^ ]| [^)]*? \)$`)

这确实要求评论是一行中的最后一件事,因此在那里添加“匹配零或更多空格”可能更好。这与字符串“(())”不匹配或尝试满足任意嵌套,因为它远远超出正则表达式可以执行的计数。

他们在计算方面可以做的是“计算特定次数”,他们不能“计算多少次等待,然后确保有相同数量的floobs”(这需要从正则表达式到一个无上下文的语法。)

Playground

答案 2 :(得分:0)

以下是匹配所有3条线路的方法:

(?m)^[\t\p{Zs}]*\([\pZs}\t](?:[^()\n]*[\pZs}\t])?\)[\pZs}\t]*$

在新regex101.com

上查看Go regex演示

详细

  • (?m) -
  • 上的多线模式
  • ^ - 由于上述原因,一行开头
  • [\t\p{Zs}]* - 0+水平空格
  • \( - (
  • [\pZs}\t] - 正好是1个水平空格
  • (?:[^()\n]*[\pZs}\t])? - 可选的序列匹配:
    • [^()\n]* - 除了()和换行符之外的0 +字符的否定字符类
    • [\pZs}\t] - 水平空白
  • \) - 文字)
  • [\pZs}\t]* - 0+水平空格
  • $ - 由于(?m),一行的结尾。

Go playground demo

package main

import (
    "regexp"
    "fmt"
)

func main() {
    var re = regexp.MustCompile(`(?m)^[\t\p{Zs}]*\([\pZs}\t](?:[^()\n]*[\pZs}\t])?\)[\pZs}\t]*$`)
    var str = ` ( )
  ( This is a comment )
    1 2 +
\ a
: square dup * ;
( foo bar 
baz )
(quux)
( ( )
(
( )`

    for i, match := range re.FindAllString(str, -1) {
        fmt.Println("'", match, "' (found at index", i, ")")
    }
}
相关问题