The main error is that you do not specify that the regex should match from the beginning to the of the checked string. Use the ^
and $
assertions.
I think you have to escape {
and }
in your regex as they have special meaning. Together they form a quantifier.
The (?<=\\\)
is better written (?<=\\\\)
. The backslash has to be double escaped as it has special meaning in both single-quoted string and PCRE regex. Using \\\
works too, because if single-quoted string contains any escape sequence except \\
and \'
, it handles it as literal backslash and letter, therefore \)
is taken literally. But explicitly escaping the backslash twice seems easier to read to me.
The regex should be
$regex = '/^(\{(?=([a-zA-Z0-9]+\|[0-9]*\|(S|D[0-9]*)\}))|[^{]|(?<=\\\\)\{)*$/';
But notice that the look-around assertions are not necessary. This regex should do the job too:
$regex = '/^([^{]|\\\{|\{[a-zA-Z0-9]+\|[0-9]*\|(S|D[0-9]*)\})*$/';
Any non-{
characters are matched by the first alternative. When a {
is read, one of the remaining two alternatives is used. Either the pattern for the brace thing matches, or the regex engine backtracks one character and tries to match \{
character sequence. If it fails, both ways, it backtracks further till it reaches string start and fails completely.