Что означает « » регулярное выражение?

Я нашел его в следующем регулярном выражении:

\[(?:[^][]|(?R))*\] 

Он соответствует квадратным скобкам (с их содержимым) вместе с вложенными квадратными скобками.

[^][] – это класс символов, который означает все символы, кроме [ и ] .

Вы можете избежать экранирования [ и ] специальных символов, поскольку это не является двусмысленным для PCRE, механизма регулярных выражений, используемого в preg_ функциях.

Так как [^] неверно в PCRE, единственный способ для синтаксического анализа регулярного выражения состоит в том, что ] находится внутри класса символов, который будет закрыт позже. То же самое с тем, что следует. Он не может повторно открыть класс символов (кроме класса символов POSIX [:alnum:] ) внутри класса символов. Тогда последнее ] ясно; это конец класса символов. Тем не менее, [ вне класса символов должен быть экранирован, поскольку он анализируется как начало класса символов.

Точно так же вы можете писать []] или [[] или [^[] не выходя из [ или ] в классе символов.

Вы можете использовать этот синтаксис с несколькими регулярными выражениями: PCRE (PHP, R), Perl, Python, Java, .NET, GO, awk, Tcl ( если вы разделите свой шаблон с фигурными скобками, спасибо Donal Fellows ), …

Но не с: Ruby, JavaScript ( кроме IE <9 ), …

Как заметил м.буэтнер, [^]] не является двусмысленным, потому что ] является первым символом, [^a]] рассматривается как все, что не является a а затем a ] . Чтобы иметь a и ] , вы должны написать: [^a\]] или [^]a]

В частном случае JavaScript спецификация разрешает [] как токен регулярного выражения, который никогда не совпадает (другими словами, [] всегда терпит неудачу) и [^] как регулярное выражение, которое соответствует любому символу . Тогда [^]] рассматривается как любой символ, за которым следует а ] . Фактическая реализация различна, но современный браузер обычно придерживается определения в спецификации.

Сведения о шаблоне:

 \[ # literal [ (?: # open a non capturing group [^][] # a character that is not a ] or a [ | # OR (?R) # the whole pattern (here is the recursion) )* # repeat zero or more time \] # a literal ] 

В вашем примере шаблона вам не нужно избегать последнего ]

Но вы можете сделать то же самое с этим шаблоном, немного оптимизированным, и более полезную причину можно использовать повторно как подшаблон (?-1) ) : (\[(?:[^][]+|(?-1))*+])

 ( # open the capturing group \[ # a literal [ (?: # open a non-capturing group [^][]+ # all characters but ] or [ one or more time | # OR (?-1) # the last opened capturing group (recursion) # (the capture group where you are) )*+ # repeat the group zero or more time (possessive) ] # literal ] (no need to escape) ) # close the capturing group 

или лучше: (\[[^][]*(?:(?-1)[^][]*)*+]) что позволяет избежать затрат на чередование.