使用Regex解析面向空白的conf文件

时间:2013-12-03 20:17:52

标签: regex pcre

我正在尝试解析一个gitolite.conf文件,这是一个面向空白的conf文件,带有一些正则表达式。最糟糕的问题是某些选项可能出现在任何地方:

@staff              =   dilbert alice           # line 1
@projects           =   foo bar                 # line 2

repo @projects baz                              # line 3
    RW+             =   @staff                  # line 4
    -       master  =   ashok                   # line 5
    RW              =   ashok                   # line 6
    R               =   wally                   # line 7

    config hooks.emailprefix = '[%GL_REPO] '    # line 8

检查“master”属性。有些回购有它们,有些没有。这是一个真正的痛苦。

2 个答案:

答案 0 :(得分:1)

此答案假定将键/值对提取到捕获组中,其中 key =之前的连续非空格组成值包括=之后但#之前的所有内容,修剪前导/尾随空格。

基本版

([^\s]+)\s*=\s*((?:\s*[^\s#]+)*)

Regular expression visualization

更高级版本

上面的正则表达式不能很好地处理引用的字符串(例如prefix = ' Quoted with # and leading/trailing whitespace ')。正则表达式在这种情况下不是很好,但简单的情况可以按如下方式处理:

([^\s]+)\s*=\s*('[^']*'|"[^"]*"|(?:(?:\s*[^\s#]+)*))

Regular expression visualization

以下是演示,如果您需要查看捕获的内容并更多地使用它:Debuggex Demo

答案 1 :(得分:0)

首先,您应该知道Regex并非完全可以实现这一点。 Regex是一个很好的解析常规语言(包括某些类型的配置文件)的工具,但是一旦你进入“嗯,这条线实际上是一个标题行,我们需要它下面的所有行,并且有些行可能有这个令牌,而其他行可能没有“,它会变得非常混乱。我不是说这是不可能的,但是你要浪费一点时间来调试你的Regex模式而不是用你正在使用它的任何语言写一个解析器。

其次,如果你要问一个关于Regex的问题,那么从表达式中知道你想要什么总是有帮助的。你想要标记所有内容,你只想要配置键,你只想要评论吗?

话虽如此,我最好的猜测,这是一个让你开始的表达方式:

^(?:([^=#]+?)\s.?=?\s.?([^=#]+?)\s.?(?:#|$))

使用此表达式,请应用gm标记(全局和多行)。在PCRE中,这看起来像:

/^(?:([^=#]+?)\s.?=?\s.?([^=#]+?)\s.?(?:#|$))/gm

有两个捕获组,一个是=符号前面的任何一个,另一个是后面的内容。如果没有=符号,则第一个捕获组包含所有内容。 “#”之后的任何内容都会被忽略。

这是一个演示的小提琴:http://www.rexfiddle.net/eQexbZU