Behavior of parenthesis in match
Hi community,
I just encountered the following
pm.isMatch("CON.md", "!(**/*.md)",{dot:true}) ? "match" : "no match" - > returns match
pm.isMatch("CON.md", "!(*.md)",{dot:true}) ? "match" : "no match" - > returns no match
without negation
pm.isMatch("CON.md", "**/*.md",{dot:true}) ? "match" : "no match" - > returns match
pm.isMatch("CON.md", "(**/*.md)",{dot:true}) ? "match" : "no match" - > returns no match
Why is the parenthesis matter? I appreciate some help.
I realize this maybe similar to https://github.com/micromatch/picomatch/issues/104, can someone please confirm?
This is correct. I believe parentheses are matched as literal characters when no preceded by an extglob charcter (!?@*+).
This is correct. I believe parentheses are matched as literal characters when no preceded by an extglob charcter (
!?@*+).
Thank you for the reply @jonschlinkert, but please take a look at the first one, even with negation, the CON.md is still matched, returning the same result when it is not with negation. Is there a correct way to do it?
I'm trying to use Picomatch to ignore files before processing other files in a repository (that is do not know what to include, we can only exclude known ones), but as you can see here in the screenshot, it is not recognizing the files at root level when I use **/*.md, is there any way that I can fix this? I've been scratching my head for hours...

I can confirm that problems only occur whenever a double asterisk appears at first position in an expression, so I can only avoid leading **, plus using * to help catch the missing files.
It might be a bug that !(**/*.md) is matching CON.md. It looks like it ought to be considered a bug, unless I'm forgetting some rule in bash glob. (fwiw, negation extglobs are difficult to get right. But negation extglobs with nested globstars --double *-- are very difficult to get right (this is mainly due to the limitation of JavaScript's regex engine and the absence of useful features like atomic groups. Picomatch will eventually be updated to use lookbehinds, which will help with this, but the community and browsers are not quite ready for those yet. We can't rely on transpilers to properly re-create lookbehinds in a backward compatible way).
Any help from contributors would be appreciated, or I can look into this as soon as I get a chance.
Suggestions
In the meantime, a couple of suggestions for how you're doing matching:
If you're doing to use the same pattern multiple times, use the main function returned by picomatch to create a matcher function instead of calling pm.isMatch() each time.
const isMatch = pm('!(**/*.md...)', { dot: true });
// then
isMatch('abc.md');
isMatch('foo/abc.md');
Instead of using a negative extglob with multiple conditions (!(**/*.md|....)), either pass an array of globs or try using braces, or a combination:
['!**/*.md', '!**/*.txt', ...]
// or
['!**/*.{md,txt}', ...]
// or
'!**/*.{md,txt,gitignore,licenserc.yaml,codestyle.xml}'
also, thank you for creating the issue and for helping to figure this out!
also, thank you for creating the issue and for helping to figure this out!
I should thank you, without Picomatch our open-source projects will be wasting a lot of CI time at non-functional file changes.