英文:
Negative lookbehind with optional suffix without duplication
问题
I am writing regex that finds all stings with these conditions:
- not starting with 
foo/orbar/or withfoo(end of line) orbar(end of line) - not ending with 
/bazor/quxand not ending with/baz/or/qux/ 
Examples that should not match:
foo
bar/nomatch
/nomatch/baz
nomatch/baz/
Examples should match:
foomatch
bazmatch
/baz/match
The regex I came up with combines a negative lookahead and a negative lookbehind:
/(?!(foo|bar)(\/|$)).*(?<!(\/)(baz|qux)(\/|$))/gm
My problem: the negative lookbehind needs to have a fixed width (ie: I cannot use (\/|$) to check for an optional slash at the end of the string). I could solve this by creating the following rule: /(?!(foo|bar)(\/|$)).*(?<!(\/)(baz|qux))(?<!(\/)(baz|qux)\/)/gm, which uses baz and qux twice. Is there another way to solve this without this duplication?
For an interactive example, see: https://regex101.com/r/bIosD0/1
英文:
I am writing regex that finds all stings with these conditions:
- not starting with 
foo/orbar/or withfoo(end of line) orbar(end of line) - not ending with 
/bazor/quxand not ending with/baz/or/qux/ 
Examples that should not match:
foo
bar/nomatch
/nomatch/baz
nomatch/baz/
Examples should match:
foomatch
bazmatch
/baz/match
The regex I came up with combines a negative lookahead and a negative lookbehind:
/(?!(foo|bar)(\/|$)).*(?<!(\/)(baz|qux)(\/|$))/gm
My problem: the negative lookbehind needs to have a fixed width (ie: I cannot use (\/|$) to check for an optional slash at the end of the string). I could solve this by creating the following rule: /(?!(foo|bar)(\/|$)).*(?<!(\/)(baz|qux))(?<!(\/)(baz|qux)\/)/gm, which uses baz and qux twice. Is there another way to solve this without this duplication?
For an interactive example, see: https://regex101.com/r/bIosD0/1
答案1
得分: 4
你可以去掉后顾条件,然后要么添加另一个负向前瞻,要么在不同条件之间使用一个交替。假设你还想禁止单独出现的 qux 和 baz。
^(?!(?:foo|bar)(?:\/|$)|(?:.*\/)?(?:baz|qux)\/?$).+
在 ^ 开始 的 (?! 负向前瞻 lookahead ) 包含两个条件:
(?:foo|bar)(?:\/|$),你已经拥有的部分,例如 不允许foo/...,foo(bar同理)|(?:.*\/)?(?:baz|qux)\/?$,或 不允许baz,baz/,前面可以有一个可选的.*\/(任意数量 的任意字符 后跟一个斜杠),以进一步禁止诸如.../baz/,.../baz在$结尾。
我使用了 (?: 非捕获组 ) 来进行交替,因为不需要捕获任何内容。
英文:
You can drop the lookbehind and either add another negative lookahead or use one and alternate inside between different conditions. Assuming you also want to disallow qux and baz alone.
^(?!(?:foo|bar)(?:\/|$)|(?:.*\/)?(?:baz|qux)\/?$).+
At ^ start the (?! negative lookahead ) contains two conditions:
(?:foo|bar)(?:\/|$)what you got already, e.g. nofoo/...,foo(same forbar)|(?:.*\/)?(?:baz|qux)\/?$OR nobaz,baz/preceded by an optional.*\/(any amount of any characters followed by a slash) to further disallow such as.../baz/,.../bazat$end.
I used (?: non-capturing groups ) for alternations because nothing needs to be captured.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论