Skip to content

Commit

Permalink
[Python] Regexp backref identifiers (#4110)
Browse files Browse the repository at this point in the history
* [Python] Regexp backref identifiers

* [Python] Loosen regex backref matches
  • Loading branch information
michaelblyons authored Jan 8, 2025
1 parent 6aa7e70 commit f615fed
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 7 deletions.
23 changes: 18 additions & 5 deletions Python/Embeddings/RegExp (for Python).sublime-syntax
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ variables:
deactivate_x_mode: (?:\?[imsLua]*-[imsLua]*x[imxsLua]*)
other_modifiers: \?(?:[ixmsLua]*-)?[ixmsLua]+

# capture group identifiers
capture_group_name: (?:[[:alpha:]_]\w*)
capture_group: (?:[1-9][0-9]*|{{capture_group_name}})

contexts:
base:
- meta_prepend: true
Expand All @@ -25,21 +29,30 @@ contexts:

group-start:
- meta_prepend: true
- match: (\?P=)([a-zA-Z_][a-zA-Z_0-9]*\w*)(?=\))
- match: (\?P=)({{capture_group_name}})(?=\))
captures:
1: keyword.other.back-reference.named.regexp
2: variable.other.backref-and-recursion.regexp
- match: (\?P)(<)([a-z]\w*)(>)
- match: (\?P)(<)({{capture_group_name}})(>)
captures:
1: keyword.other.backref-and-recursion.regexp
2: punctuation.definition.capture-group-name.begin.regexp
3: entity.name.capture-group.regexp
4: punctuation.definition.capture-group-name.end.regexp
- match: (\?)(\()([1-9][0-9]?|[a-zA-Z_][a-zA-Z_0-9]*)(\))
# We can make this more sophisticated to match the | character that separates
# yes-pattern from no-pattern, but it's not really necessary.
# We can make this more sophisticated to match the | character that separates
# yes-pattern from no-pattern, but it's not really necessary.
- match: (\?)(\()({{capture_group}})(\))
captures:
1: keyword.other.backref-and-recursion.conditional.regexp
2: punctuation.definition.group.begin.assertion.conditional.regexp
3: variable.other.back-reference.regexp
4: punctuation.definition.group.end.assertion.conditional.regexp

backrefs:
- meta_prepend: true
- match: \\g(<)({{capture_group}})(>)
scope: keyword.other.backref-and-recursion.regexp
captures:
1: punctuation.definition.capture-group-name.begin.regexp
2: variable.other.backref-and-recursion.regexp
3: punctuation.definition.capture-group-name.end.regexp
41 changes: 39 additions & 2 deletions Python/tests/syntax_test_python_strings.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,8 @@
# ^ constant.character.escape.python

regex = r'\b ([fobar]*){1}(?:a|b)?'
# ^ meta.string.python keyword.control.anchor.regexp
# ^ keyword.operator.quantifier.regexp
# ^^ meta.string.python keyword.control.anchor.regexp
# ^^^ keyword.operator.quantifier.regexp

regex = r'.* # Not a comment (yet)'
# ^^^^^^^^^^^^^^^^^^^^^ - comment
Expand All @@ -115,6 +115,43 @@
# ^ punctuation.definition.string.end.python - comment
# ^ - invalid

regex = r"(backref) \1 "
# ^^ keyword.other.backref-and-recursion.regexp
# ^ variable.other.backref-and-recursion.regexp
# ^ - keyword

regex = r'(?P<quote>[\'"]).*?(?P=quote)'
# ^^ keyword.other.backref-and-recursion.regexp
# ^ punctuation.definition.capture-group-name.begin.regexp
# ^^^^^ entity.name.capture-group.regexp - invalid
# ^ punctuation.definition.capture-group-name.end.regexp
# ^^^ keyword.other.back-reference.named.regexp
# ^^^^^ variable.other.backref-and-recursion.regexp - invalid

regex = r'(?P<Quote>[\'"]).*?(?P=Quote)'
# ^^ keyword.other.backref-and-recursion.regexp
# ^ punctuation.definition.capture-group-name.begin.regexp
# ^^^^^ entity.name.capture-group.regexp - invalid
# ^ punctuation.definition.capture-group-name.end.regexp
# ^^^ keyword.other.back-reference.named.regexp
# ^^^^^ variable.other.backref-and-recursion.regexp - invalid

regex = r'(?P<quote>[\'"]).*?\g<quote>'
# ^^ keyword.other.backref-and-recursion.regexp
# ^ punctuation.definition.capture-group-name.begin.regexp
# ^^^^^ entity.name.capture-group.regexp - invalid
# ^ punctuation.definition.capture-group-name.end.regexp
# ^^ keyword.other.backref-and-recursion.regexp
# ^^^^^ variable.other.backref-and-recursion.regexp - invalid

regex = r'(?P<Quote>[\'"]).*?\g<Quote>'
# ^^ keyword.other.backref-and-recursion.regexp
# ^ punctuation.definition.capture-group-name.begin.regexp
# ^^^^^ entity.name.capture-group.regexp - invalid
# ^ punctuation.definition.capture-group-name.end.regexp
# ^^ keyword.other.backref-and-recursion.regexp
# ^^^^^ variable.other.backref-and-recursion.regexp - invalid

regex = r'''\b ([fobar]*){1}(?:a|b)?'''
# ^ keyword.control.anchor.regexp
# ^ keyword.operator.quantifier.regexp
Expand Down

0 comments on commit f615fed

Please sign in to comment.