正则表达式匹配字符串(蓝色:bar和darkblue:foo)到深蓝色

时间:2017-10-30 17:28:45

标签: php regex

我需要写一个正则表达式,它可以匹配以"开头的字符串("或空格,以冒号结尾(开头和结尾字符都应该从匹配结果中排除)并排除以下三个字(仅限完全匹配):红色,绿色,蓝色。

例如:

输入1 :(绿色:条形和黑色:foo)
匹配结果:黑色

输入2 :(蓝色:条形和暗蓝色:foo)
匹配结果: darkblue

输入3 :(黄色:条形和灰色:foo)
匹配结果:黄灰色

输入4 :( greengarden:bar AND blue:foo)
匹配结果: greengarden

1 个答案:

答案 0 :(得分:1)

这些是我编写的一些模式(按照“步数”效率最低效率的顺序):

步数基于此样本输入:

(green:bar AND black:foo)
(blue:bar AND darkblue:foo)
(yellow:bar AND grey:foo)
(greengarden:bar AND red:foo)
  • /(?:red|blue|green)(*SKIP)(*FAIL)|[a-z]+(?=:)/ Demo(513步)

  • /\b(?!red:|blue:|green:)[a-z]+(?=:)/ Demo(372步)

  • /(?<=\(|AND )(?!red:|blue:|green:)[^:]*/ Demo(319步)

  • /(?<=\(|AND )(?:(?:red:|blue:|green:)(*SKIP)(*FAIL)|[^:]+)/ Demo(304步)

  • /(?:\(|AND )\K(?!red:|blue:|green:)[^:]*/ Demo(291步)

  • /(?:\(|AND )\K(?!red\b|blue\b|green\b)[^:]+/ Demo(291步)

  • /[( ]\K(?!red\b|blue\b|green\b)[a-z]+/ Demo(172步)

这个最终模式是表现最佳的模式,并充分利用输入数据的严格格式 - 与大写,开括号和每行两个空格有关。

找到左括号或空格,然后使用\K重新启动全字符串匹配,取消任何完全redbluegreen的子字符串的资格并停止匹配最后一个小写字母。

在正则表达式中,通过使用窄字符类([]&amp; [^])来实现速度提升,限制备选方案(管道|),“外观”和捕获/非捕获组。

我的模式故意避免制作捕获组,因为它们只导致输出数组膨胀。所有您想要的“颜色”子串都可以在preg_match_all()返回的fullstring [0]匹配子阵列中找到。

代码:(Demo

$string='(green:bar AND black:foo)
    (blue:bar AND darkblue:foo)
    (yellow:bar AND grey:foo)
    (greengarden:bar AND red:foo)';

var_export(preg_match_all('/[( ]\K(?!red\b|blue\b|green\b)[a-z]+/',$string,$out)?$out[0]:'fail');

输出:

array (
  0 => 'black',
  1 => 'darkblue',
  2 => 'yellow',
  3 => 'grey',
  4 => 'greengarden',
)