I am writing a snippet for the Vim plugin UltiSnips which will trigger on a regex pattern (as supported by Python 3). To avoid conflicts I want to make sure that my snippet only triggers when contained somewhere inside of $$___$$. Note that the trigger pattern might contain an indefinite string in front or behind it. So as an example I might want to match all "a" in "$$ccbbabbcc$$" but not "ccbbabbcc". Obviously this would be trivial if I could simply use indefinite look behind. Alas, I may not as this isn't .NET and vanilla Python will not allow it. Is there a standard way of implementing this kind of expression? Note that I will not be able to use any python functions. The expression must be a self-contained trigger.
Asked
Active
Viewed 134 times
0
-
Would non-greedy matching suffice: i.e. `\$\$.*?(a).*?\$\$`? – ekhumoro Aug 13 '20 at 15:16
-
One thing that isn't clear in the question is whether there will be one snippet that always matches the same pattern, or several independent snippets that each matches a different pattern. If the latter, it becomes more dififcult to determine where each snippet begins and ends. – ekhumoro Aug 13 '20 at 15:56
-
These could be different snippets each triggered by their own respective pattern X if and only if that X is found inside of the double dollar signs. That way pattern X can be used for different snippets when not found inside of dollar signs. – Shadow43375 Aug 13 '20 at 16:04
-
So far, your specification seems ambiguous. If you have three *independent* snippets matching "a", "b" and "c", how should the following input be parsed: `$$-b-$$ a $$-c-$$`? – ekhumoro Aug 13 '20 at 16:33
-
If you have three *independent* snippets matching "a", "b" and "c", there is no unambiguous way to parse input like`$$-b-$$ a $$-c-$$`. Probably the best way to solve this would be to use different symbols for the start/end markers. So something like `$@ - a - @$` would work (i.e. much like the syntax for inline comments in some languages: `/* foo */`). – ekhumoro Aug 13 '20 at 19:04
3 Answers
1
If what you are looking for only occurs once between the '$$', then:
\$\$.*?(a)(?=.*?\$\$)
This allows you to match all 3 a
characters in the following example:
\$\$)
Matches '$$'.*?
Matches 0 or more characters non-greedily(?=.*?\$\$)
String must be followed by 0 or more arbitrary characters followed by '$$'
The code:
import re
s = "$$ccbbabbcc$$xxax$$bcaxay$$"
print(re.findall(r'\$\$.*?(a)(?=.*?\$\$)', s))
Prints:
['a', 'a', 'a']

Booboo
- 38,656
- 3
- 37
- 60
-
This will fail for input strings like `$$-b-$$ a $$-c-$$` (i.e. it will report a match for `a` when it shouldn't). – ekhumoro Aug 13 '20 at 16:19
-
@ekhumoro I agree that it will find a match but I for `a` with that input but I am not sure why it shouldn't when the OP specifies that they are looking for the occurrence of an `a` between `$$` and `$$`. Anyway, my regex is based on my interpretation of the question, which seems quite clear English-wise. – Booboo Aug 13 '20 at 17:24
-
The question may *seem* to specify that, but the OP states otherwise in the comments. – ekhumoro Aug 13 '20 at 18:44
0
The following should work:
re.findall("\${2}.+\${2}", stuff)
Breakdown:
Looks for two '$'
"\${2}
Then looks for one or more of any character
.+
Then looks for two '$' again

josephdiniso
- 31
- 3
-
This will match ALL of one or more character between the dollar signs. But I only want to match the 'a' between the dollars signs and ignore all the other characters. – Shadow43375 Aug 13 '20 at 15:09
0
I believe this regex would work to match the a
within the $$
:
text = '$$ccbbabbcc$$ccbbabbcc'
re.findall('\${2}.*(a).*\${2}', text)
# prints
['a']
Alternatively:
A simple approach (requiring two checks instead of one regex) would be to first find all parts enclosed in your quoting text, then check if your search string is present withing.
example
text = '$$ccbbabbcc$$ccbbabbcc'
search_string = 'a'
parts = re.findall('\${2}.+\${2}', text)
[p for p in parts if search_string in p]
# prints
['$$ccbbabbcc$$']

Haleemur Ali
- 26,718
- 5
- 61
- 85
-
Remember that in the example 1) I only want to match the 'a' inside $$ccbbabbcc$$ and 2) I am not able to use Python functions – Shadow43375 Aug 13 '20 at 15:07