Eneko
Eneko

Reputation: 2107

Capturing regexp which excludes two literals

In a Spring controller I want an updateuser endpoint, a deleteuser endpoint and a generic one that captures the rest of options:

@PostMapping(value = "/{action:^((?!(updateuser|deleteuser)).)+}")
// Do something depending on `action`, need to capture the match

@PostMapping(value = "/updateuser")
// Update user

@PostMapping(value = "/deleteuser")
// Delete user

Using that regexp throws:

The number of capturing groups in the pattern segment (^((?!updateuser|deleteuser).)*) does not match the number of URI template variables it defines, which can occur if capturing groups are used in a URI template regex. Use non-capturing groups instead.

I have no problem if I use @PostMapping(value = "/{action:^.*(?!updateuser)}")

Which would be the correct regexp?

Upvotes: 0

Views: 101

Answers (1)

The fourth bird
The fourth bird

Reputation: 163267

You can exclude the updateuser and deleteuser by using a single negative lookahead without a capture group, instead of using a tempered greedy token approach matching a single character followed by the assertion.

^(?!.*(?:update|delete)user).+$

If it should be more strict, you can use word boundaries to prevent partial word matches:

^(?!.*\b(?:update|delete)user\b).+$

See a regex demo.

Upvotes: 2

Related Questions