I am writing a regex for my git commit-msg
hook and can't deal with the last part.
This is my regex
/^GRP\-[0-9] \s(FIX|CHANGE|HOTFIX|FEATURE){1}\s(CORE|SHARED|ADM|CSR|BUS|OTHER){1}\s-\s. /
My commit messages can have 2 variations.
- GRP-0888 FIX OTHER - (jest.config.js) : Fix testMatch option issue
- GRP-0888 FIX OTHER - Fix testMatch option issue
My current regex works well with both as it completes the check after -
.
So basically after the dash, it doesn't take care of checking the format.
I want it to check these 2 conditions and match them respectively.
- If after the dash it meets
(
then continue with that pattern and do all the checks
Check if the opening and closing brackets are there and after the closing bracket it has a space and
:
and again space and the rest of the commit description.It should match the 1st pattern.
- If it meets an Alphanumeric character after the
-
then it matches the 2nd pattern
I have tried to use a disjunction
in a capturing group but somehow it fails. Actually, I am guessing why it is failing as the second condition can always cover everything.
/^GRP\-[0-9] \s(FIX|CHANGE|HOTFIX|FEATURE){1}\s(CORE|SHARED|ADM|CSR|BUS|OTHER){1}\s-\s(\(. \)\s:\s. |. )/
UPDATED
These commit message patterns are invalid and shouldn't pass
- GRP-0988 FIX CORE - (Some change)
- GRP-0988 FIX CORE - (Some change) - Some description
- GRP-0988 FIX CORE - (
- GRP-0988 FIX CORE - ()
- GRP-0988 FIX CORE - (Some change
- GRP-0988 FIX CORE - Some change)
CodePudding user response:
This is the regex after the dash: (?:(\(.*?\))(?:\s:\s))?(?!\(.*?\)(?:\s-\s)?)(. )
(?:(\(.*?\))(?:\s:\s))?
- Optionally match the previous two parts, without capturing(\(.*?\))
- Match and capture the part within parentheses. Use the non-greedy quantifier*?
to prevent leaking into the rest of the string if there is another)
after the part you want to match.(?:\s:\s)
- Match and discard the colon and surrounding spaces
(?!\(.*?\)(?:\s-\s)?)
- Negative lookahead to ensure it does not match messages such as(Some change)
and(Some change) - Some description
\(.*?\)
- Match stuff within parentheses(?:\s-\s)?
- Optionally match a colon surrounded by spaces
(. )
- Match and capture the rest the commit message
let formats = [
"GRP-0888 FIX OTHER - (jest.config.js) : Fix testMatch option issue",
"GRP-0888 FIX OTHER - Fix testMatch option issue",
"GRP-0900 FIX CORE - (Some change) - Some change. If there are (Some text)",
"GRP-0988 FIX CORE - (Some change)",
"GRP-0988 FIX CORE - (Some change) - Some description",
]
let regex = /^GRP\-[0-9] \s(FIX|CHANGE|HOTFIX|FEATURE)\s(CORE|SHARED|ADM|CSR|BUS|OTHER)\s-\s(?:(\(.*?\))(?:\s:\s))?(?!\(.*?\)(?:\s-\s)?)(. )/
for (let format of formats) {
console.log(format.match(regex))
}
CodePudding user response:
You might use:
^GRP-[0-9] \s(FIX|CHANGE|HOTFIX|FEATURE)\s(CORE|SHARED|ADM|CSR|BUS|OTHER)\s-\s(?=[^a-zA-Z0-9]*[a-zA-Z0-9])(?:\([^()]*\)\s:\s)?[^()]*$
Explanation
^
Start of stringGRP-[0-9] \s
MatchGRP-
1 digits and a whitespace char(FIX|CHANGE|HOTFIX|FEATURE)
Capture one of the alternatives in group 1\s
Match a single whitespace char(CORE|SHARED|ADM|CSR|BUS|OTHER)
Capture one of the alternatives in group 2\s-\s
Match-
between 2 whitespace chars(?=[^a-zA-Z0-9]*[a-zA-Z0-9])
Positive lookahead, assert an alphanumeric to the right(?:\([^()]*\)\s:\s)?
Optionally match(...)
followed by:
[^()]*
Match optional chars other than(
or)
$
End of string
See a regex101 demo
const regex = /^GRP-[0-9] \s(FIX|CHANGE|HOTFIX|FEATURE)\s(CORE|SHARED|ADM|CSR|BUS|OTHER)\s-\s(?=[^a-zA-Z0-9]*[a-zA-Z0-9])(?:\([^()]*\)\s:\s)?[^()]*$/;
[
"GRP-0888 FIX OTHER - (jest.config.js) : Fix testMatch option issue",
"GRP-0888 FIX OTHER - Fix testMatch option issue",
"GRP-0988 FIX CORE - (Some change)",
"GRP-0988 FIX CORE - (Some change) - Some description",
"GRP-0988 FIX CORE - (",
"GRP-0988 FIX CORE - ()",
"GRP-0988 FIX CORE - (Some change",
"GRP-0988 FIX CORE - Some change)"
].forEach(s =>
console.log(`${regex.test(s)} ---> ${s}`)
)