简体   繁体   中英

Regular expression, lost result group

My cpp application is trying to parse a string with pattern:

^\/color( set| update)? (#[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})|([a-zA-Z]{1,20})$

Test run

/color set #ffffff - get 2 groups('set and '#ffffff') 在此处输入图片说明

/color set red - get 1 group with 'red', what happened to the group with 'set'? 在此处输入图片说明

The issue is, you have an incorrect / unnecessary grouping. Use the following :

^\/color\s(set|update)?\s?(#[A-Fa-f0-9]{6}|#[A-Fa-f0-9]{3}|[a-zA-Z]{1,20})$

DEMO

Your issue is with this section of the regex.

(#[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})|([a-zA-Z]{1,20})

With the way you have them grouped and the precedence of the OR operator, it is basically being evaluated as capture if either of these two regexes are true:

^\/color( set| update)? (#[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})
([a-zA-Z]{1,20})$

Because of the string "/color set red" not matching the hexadecimal check, it determines the left side is false and only the right is true. Hence, why it is capturing the right.

I suggest rewriting your regex as this. This way it accounts for one or more space and tab characters between each argument in the string.

^\/color[ \t]*(set|update)?[ \t]+(\#[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3}|[a-zA-Z]{1,20})$

I've added named groups and fixed an issue with the second whitespaces, which lead to /color red not being matched, in the case of the operation being omitted.

^\\/color\\s+(?<op>set|update)?\\s*(?<color>#[AFaf09]{6}|[A-Fa-f0-9]{3}|[a-zA-Z]{1,20})\\s*$

Click here to test the regex. Also, below you'll find a version without named captures, since SebastianRedl pointed out, that C++ does not support this feature.

^\\/color\\s+(set|update)?\\s*(#[AFaf09]{6}|[A-Fa-f0-9]{3}|[a-zA-Z]{1,20})\\s*$

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM