deemon
deemon

Reputation: 131

Regular expression that match a text if it contains a string ONLY once

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

Answers (2)

Wiktor Stribiżew
Wiktor Stribiżew

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

mpcabd
mpcabd

Reputation: 1807

I think you got it right, it's only missing ^ and $ anchors to make sure that your regex matches the whole string. Check here for an example.

Upvotes: 0

Related Questions