Recursive RegEx (?R), (?-2)
- ?> は Atomic Grouping
- (?-2) は Recursion
- Atomic Grouping と Recursion は常にペアで使う。
- (?-2) は "Call recursively 2 outside parenthesis"
- (?-2) が示す parenthesis を non-capture (?:...)にすることはできない。
/(@[^@{};]+(?:;|(({(?:(?>[^{}"']+|\s+|"(?:\\"|\\\n|[^"\n])*?"|'(?:\\'|\\\n|[^'\n])*?')|(?-2))*})))|[^@{}\s][^@{}]*(({(?:(?>[^{}"']+|\s+|"(?:\\"|\\\n|[^"\n])*?"|'(?:\\'|\\\n|[^'\n])*?')|(?-2))*})))/su
@charset "utf-8";
@IDENTIFIER (RULE);
@supports (display: flex) {
@media screen and (min-width: 900px) {
article {
display: flex;
}
}
}
.bad-block {{}
.simplest-block{}
#main .header {
width:100px;
}
.nested-block {{}}
.complex>.selector {
abc { "this is a string" }
}
.good-multi-line-string {
abc {
'1234\
5678'
} xyz
}
.bad-multi-line-string {
abc {
'1234
5678'
} xyz
}
.string-with-escape { abc { '12}34\'5678' } xyz } remaining
Array
(
[0] => @charset "utf-8";
[1] => @IDENTIFIER (RULE);
[2] => @supports (display: flex) {
@media screen and (min-width: 900px) {
article {
display: flex;
}
}
}
[3] => .simplest-block{}
[4] => #main .header {
width:100px;
}
[5] => .nested-block {{}}
[6] => .complex>.selector {
abc { "this is a string" }
}
[7] => .good-multi-line-string {
abc {
'1234\
5678'
} xyz
}
[8] => .string-with-escape { abc { '12}34\'5678' } xyz }
)