Yes there is. You can combine a negative look and a back link:
"(\\[[^\\[\\]]*\\])(?!.*\\1)"
This will only correspond to the fact that the one that was matched by your actual template no longer appears in the line. Effectively this means that you always get the last occurrence of each match, so you can get them in a different order:
[inputString] [userName]
If the order is a problem for you (i.e. if it is crucial to order them by their first occurrence), you cannot do this only with the help of a regular expression. To do this, you need the look * behind *, and this is not supported by Java.
Further reading:
Some notes on the general solution
Please note that this will work with any pattern whose matches are non-zero. The general solution is simple:
(yourPatternHere)(?!.*\1)
(I left a double backslash because this only applies to a few languages.)
If you want it to work with templates that have zero width matches (because you only want to know the position and use search queries only for some reason), you can do this:
(zeroWidthPatternHere)(?!.+\1)
Also note that (as a rule) you may need to use the "singleline" or "dotall" option if your input may contain line breaks (otherwise the scan will only be checked in the current line). If you cannot or do not want to activate this (because you have a template that includes periods that should not coincide with line breaks or because you use JavaScript), this is a general solution:
(yourPatternHere)(?![\s\S]*\1)
And to make this answer more widely applicable, here is how you could only match the first occurrence of each match (in a variable-length engine with lookbehinds, such as .NET):
(yourPatternHere)(?<!\1.*\1) or (yourPatternHere)(?<!\1[\s\S]*\1)
Martin ender
source share