Reputation: 131
I would like to write a regular expression that matches a text if it contains a string ONLY once. The text must contain <scr>
only once. Here are some examples:
hello-<scr>Keephello-endofstring
//ok; <scr>
occurs once
test-<scr>bla<scr>bla-end
//NOT ok; <scr>
occurs 2 times
hello-Keephello-end
//NOT ok; <scr>
doesn't occur
I tried with the following regex:
((?:(?<!<scr>).)*<scr>(?:(?!<scr>).)*)
The first negative lookbehind ensures that <scr>
doesn't occur.
Than <scr>
must follow.
After this a negative lookahead ensures that no more <scr>
follow.
It does not work.
I would like to know how this can be done with regex? (with explanation)
Upvotes: 7
Views: 10244
Reputation: 626845
To check if text contains some substring only once, you need to check match all characters that do not constitute <scr>
, then match <scr>
, and use a negative look-ahead to check if there is no <scr>
further, and consume all characters. Also, line/string boundaries ^
/$
are a must:
^(?:(?!<scr>).)*<scr>(?!.*<scr>).*$
See demo
EXPLANATION:
^
- Start of line (as m
multiline option is ON)(?:(?!<scr>).)*
- A non-capturing group to match each character (not a newline - for that, you need to also add s
singleline option) that is not preceded with <scr>
<scr>
- Our literal <scr>
(?!.*<scr>)
- The negative lookbehind checking that we do not have <scr>
any more .*$
- Subpattern matching the rest of the characters to the end of the line.Upvotes: 5