正则表达式:将可选字符串匹配到组

问题描述

我有一个描述对象的文件,其中对象的某些属性是可选的。例如(颜色是可选的):

type=dog
sex=male
name=wolf
color=brown
type=dog
sex=male
name=bob
type=cat
sex=male
name=tom
color=black
type=dog
sex=female
name=simona
color=white

我正在寻找一种正则表达式,可以为我的狗“名称”-“颜色”提供一对属性。我正在等待这样的事情:

wolf - brown
bob - 
simona - white

我从

开始
type=dog[\s\S]*?name=(\w+)[\s\S]*?color=(\w+)

哪个错误

wolf - brown
bob - black
simona - white

然后我用颜色分组(颜色相同)并添加“?”量词:

type=dog[\s\S]*?name=(\w+)[\s\S]*?(color=(\w+))?

但是,我没有在所有比赛中输掉第二组,而不是期望的结果:

wolf - 
bob - 
simona - 

我的表情出了什么问题以及如何实现我的目标。请不要使用Lookbehind,Lookahead和Conditional。 VBScript无法实现它们。

My example on regex101.com

解决方法

设置regex.Multiline = True并使用以下正则表达式:

^type=dog[\s\S]*?^name=(\w+)(?:(?:(?!^type=)[\s\S])*?^color=(\w+))?

请参见regex demo

详细信息

  • ^-一行的开头
  • type=dog-字符串
  • [\s\S]*?-最少0个或更多字符
  • ^-一行的开头
  • name=-文字字符串
  • (\w+)-第1组:任何一个或多个字母,数字或下划线
  • (?:(?:(?!^type=)[\s\S])*?^color=(\w+))?-一个可选的非捕获组,匹配出现1或0次
    • (?:(?!^type=)[\s\S])*?-不会在行首开始出现type=子字符串的任何字符,最多0次或更多,且尽可能少。
    • ^color=-color=子串行的开头
    • (\w+)-第2组:任何一个或多个字母,数字或下划线