我正在尝试解析一个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”属性。有些回购有它们,有些没有。这是一个真正的痛苦。
答案 0 :(得分:1)
此答案假定将键/值对提取到捕获组中,其中 key 由=
和之前的连续非空格组成值包括=
之后但#
之前的所有内容,修剪前导/尾随空格。
基本版
([^\s]+)\s*=\s*((?:\s*[^\s#]+)*)
更高级版本
上面的正则表达式不能很好地处理引用的字符串(例如prefix = ' Quoted with # and leading/trailing whitespace '
)。正则表达式在这种情况下不是很好,但简单的情况可以按如下方式处理:
([^\s]+)\s*=\s*('[^']*'|"[^"]*"|(?:(?:\s*[^\s#]+)*))
以下是演示,如果您需要查看捕获的内容并更多地使用它:Debuggex Demo
答案 1 :(得分:0)
首先,您应该知道Regex并非完全可以实现这一点。 Regex是一个很好的解析常规语言(包括某些类型的配置文件)的工具,但是一旦你进入“嗯,这条线实际上是一个标题行,我们需要它下面的所有行,并且有些行可能有这个令牌,而其他行可能没有“,它会变得非常混乱。我不是说这是不可能的,但是你要浪费一点时间来调试你的Regex模式而不是用你正在使用它的任何语言写一个解析器。
其次,如果你要问一个关于Regex的问题,那么从表达式中知道你想要什么总是有帮助的。你想要标记所有内容,你只想要配置键,你只想要评论吗?
话虽如此,我最好的猜测,这是一个让你开始的表达方式:
^(?:([^=#]+?)\s.?=?\s.?([^=#]+?)\s.?(?:#|$))
使用此表达式,请应用g
和m
标记(全局和多行)。在PCRE中,这看起来像:
/^(?:([^=#]+?)\s.?=?\s.?([^=#]+?)\s.?(?:#|$))/gm
有两个捕获组,一个是=
符号前面的任何一个,另一个是后面的内容。如果没有=
符号,则第一个捕获组包含所有内容。 “#”之后的任何内容都会被忽略。
这是一个演示的小提琴:http://www.rexfiddle.net/eQexbZU