简单的CSV词法分析器

Ado*_*obe 8 python regex csv pygments

我想按列列出带有pygments的CSV文件,如下所示:

在此输入图像描述

看到同一列用相同的颜色着色.

目前pygments不包括CSV解析器,因为CSV被认为是模糊的格式.所以我试着自己写一个最小的.这是我试过的:

tokens = {
    'root': [
        (r'^[^,\n]+', Name.Function), # first column
        (',', Comment),               # separator
        (r'[^,\n]+', Name.Decorator), # second column
        (',', Comment),               # separator
        (r'[^,\n]+', Name.Constant),  # third column
        (',', Comment),               # separator
    ],
}
Run Code Online (Sandbox Code Playgroud)

但它没有为任何列着色,但首先:

在此输入图像描述

据我所知,pygments的工作原理是尝试逐个匹配正则表达式:当前正则表达式不匹配时 - 它会转到下一个,然后再重复一次.如果没有匹配则发出错误并前进一个字符(并将其放在红色框中).对于像嵌套注释这样的高级情况,有些状态,但我认为对于CSV,一个状态可能就足够了.

然后我尝试了:

tokens = {
    'root': [
        (',', Comment),                           # separator
        (r'^[^,\n]+', Name.Function),             # first column
        (r'(?:^[^,\n]+)[^,\n]+', Name.Decorator), # second column
    ],
}
Run Code Online (Sandbox Code Playgroud)

但它将所有列作为第二列着色:

在此输入图像描述

这是一个示例数据:

account_id,parent_account_id,name,status
,A001,English,active
A001,,Humanities,active
A003,A001,,active
A004,A002,Spanish,
Run Code Online (Sandbox Code Playgroud)

在Emacs中,我设法得到了我想要的东西:

(add-hook 'csv-mode-hook
             (lambda ()
               "colors first 8 csv columns differently"
               (font-lock-add-keywords nil '(("^\\([^,\n]*\\),"
                                              1 'font-lock-function-name-face)))
               (font-lock-add-keywords nil '(("^\\([^,\n]*\\),\\([^,\n]*\\)"
                                              2 'font-lock-variable-name-face)))
               (font-lock-add-keywords nil '(("^\\([^,\n]*\\),\\([^,\n]*\\),\\([^,\n]*\\)"
                                              3 'font-lock-keyword-face)))
               (font-lock-add-keywords nil '(("^\\([^,\n]*\\),\\([^,\n]*\\),\\([^,\n]*\\),\\([^,\n]*\\)"
                                              4 'font-lock-type-face)))
))
Run Code Online (Sandbox Code Playgroud)

(我实际上添加了超过4列,但这并不重要)

这使:

在此输入图像描述

Ado*_*obe 7

哦,我用状态解决了它:

tokens = {
    'root': [
        (r'^[^,\n]*', Name.Function, 'second'),
    ],
    'second': [
        (r'(,)([^,\n]*)', bygroups(Comment, Name.Decorator), 'third'),
    ],
    'third': [
        (r'(,)([^,\n]*)', bygroups(Comment, Name.Constant), 'fourth'),
    ],
    'fourth': [
        (r'(,)([^,\n]*)', bygroups(Comment, Name.Variable), 'fifth'),
    ],
    'fifth': [
        (r'(,)([^,\n]*)', bygroups(Comment, Keyword.Type), 'unsupported'),
    ],
    'unsupported': [
        (r'.+', Comment),
        ],
}
Run Code Online (Sandbox Code Playgroud)

它以不同的方式为前5个CSV列着色,并将所有其他列作为注释:

在此输入图像描述