Exception with EXTMATCH on pattern like '!(not)_@(this|that)'
S: triage
* **OS:** Arch Linux
* **python version:** 3.12.3
* **wcmatch version:** 8.5.1
When using a pattern like `!(not)_@(this|that)` and EXTMATCH an exception `missing ), unterminated subpattern at position 5` is raised. The issue happens when a `!(pattern-list)` is followed by a `@(pattern-list)`.
As a trivialized example say I have the files `1_foo`, `2_foo` and `3_bar` and I want to match all files except the 2nd, I could use a pattern `!(2)_@(foo|bar)`. Matching the 1st file like this:
```python
from wcmatch import fnmatch
fnmatch.fnmatch('1_foo', '!(2)_@(foo|bar)', flags = fnmatch.EXTMATCH)
```
Should result `True` but instead the fnmatch call raises this exception:
```python
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.12/site-packages/wcmatch/fnmatch.py", line 86, in fnmatch
return bool(_wcparse.compile(patterns, flags, limit, exclude=exclude).match(filename))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/site-packages/wcmatch/_wcparse.py", line 787, in compile
positive, negative = compile_pattern(patterns, flags, limit, exclude)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/site-packages/wcmatch/_wcparse.py", line 739, in compile_pattern
positive.append(_compile(expanded, flags))
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/site-packages/wcmatch/_wcparse.py", line 798, in _compile
return re.compile(WcParse(pattern, flags & FLAG_MASK).parse())
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/re/__init__.py", line 228, in compile
return _compile(pattern, flags)
^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/re/__init__.py", line 307, in _compile
p = _compiler.compile(pattern, flags)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/re/_compiler.py", line 745, in compile
p = _parser.parse(p, flags)
^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/re/_parser.py", line 979, in parse
p = _parse_sub(source, state, flags & SRE_FLAG_VERBOSE, 0)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/re/_parser.py", line 460, in _parse_sub
itemsappend(_parse(source, state, verbose, nested + 1,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/re/_parser.py", line 862, in _parse
p = _parse_sub(source, state, sub_verbose, nested + 1)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/re/_parser.py", line 460, in _parse_sub
itemsappend(_parse(source, state, verbose, nested + 1,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/re/_parser.py", line 864, in _parse
raise source.error("missing ), unterminated subpattern",
re.error: missing ), unterminated subpattern at position 5
```
In bash it works:
```bash
$ touch 1_foo 2_foo 3_bar
$ ls !(2)_@(foo|bar)
1_foo 3_bar
```
关闭于 2024-05-15 2 条评论