输入:
让我们考虑下面的这个字符串
* key : foo bar *
* big key : bar*bar
* healthy : cereal bar *
sadly : without star *
输出:
我想检索每个匹配的键:值对。
正则表达式:
我的第一次成功是通过这个Regex(PCRE / Perl)实现的:
/(\n?)([^\* ].*[^ *])\s+:\s+([^\* ].*[^ *])[\s\*]+(?|\n)/g
这里是DEMO。
我的问题
我真的觉得我的正则表达很难看。主要原因是因为我无法在全局正则表达式中使用/^
和$/
而我必须使用/(\n?)...(?|\n)/g
。
是否有可能缩短上述正则表达式?
可选挑战
实际上这很容易。我的字符串应该嵌入在C注释中,我必须确保我不会尝试匹配注释块之外的内容。
(我真的不需要回答第二个棘手的问题,因为如果我编写一个脚本,我可以先匹配所有的注释块,然后找到所有的关键:值模式)。
/********************************
* key : foo bar *
* big key : bar*bar
* healthy : /*cereal bar *
sadly : without star *
********************************/
not a key : this key
答案 0 :(得分:2)
您可以将m
-flag添加到正则表达式,以使锚点^
和$
匹配字符串中每行的开头和结尾,即:
/^\s*\*?\s*([^:]+?)\s*:\s*(.*?)\s*\*?\s*$/gm
注意使用非贪婪量词(+?
和*?
)来消除量词之后可以匹配的字符,即第一个捕获组之前不会包含可选的尾随空格冒号,第二个捕获组将不包括尾部空格和行尾的可选星号。
答案 1 :(得分:1)
http://regex101.com/r/oJ8uW4/1
我使用的正则表达式是:/^\s*[*]*\s+(.*)\s+:\s+(.*?)\s+[*]*\s*$/gm
它适用于你的例子,因为not a key : this key
后面没有空格,所以它会错过不关闭whith *
的注释,也会得到带尾随空格的值。
您正在寻找的是最后一个之后的修饰符/
m
表示它是多行的,因此^
和$
可用,g
可在每行重新匹配。
缺点是,在使用/*
和*/
时,您不能依赖于^
和$
但是Avinash会证明我错了我打赌:)(他的正则表现要好于我)