使用全局修饰符的正则表达式捕获行内的单词

时间:2014-08-20 12:03:37

标签: regex pcre

输入:

让我们考虑下面的这个字符串

*     key     : foo bar        *
*     big key : bar*bar        
*     healthy : cereal bar     *
      sadly   : without star   *

输出:

我想检索每个匹配的键:值对。

  1. 'key','foo bar'
  2. 'big key','bar * bar'
  3. '健康','谷物吧'
  4. '很遗憾','没有明星'
  5. 正则表达式:

    我的第一次成功是通过这个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
    

2 个答案:

答案 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会证明我错了我打赌:)(他的正则表现要好于我)