我需要写一个正则表达式,它可以匹配以"开头的字符串("或空格,以冒号结尾(开头和结尾字符都应该从匹配结果中排除)并排除以下三个字(仅限完全匹配):红色,绿色,蓝色。
例如:
输入1 :(绿色:条形和黑色:foo)
匹配结果:黑色
输入2 :(蓝色:条形和暗蓝色:foo)
匹配结果: darkblue
输入3 :(黄色:条形和灰色:foo)
匹配结果:黄灰色
输入4 :( greengarden:bar AND blue:foo)
匹配结果: greengarden
答案 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
重新启动全字符串匹配,取消任何完全red
,blue
或green
的子字符串的资格并停止匹配最后一个小写字母。
在正则表达式中,通过使用窄字符类([]
&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',
)