Что означает регулярное выражение "[^][]"?

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

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

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

1 ответ

Решение

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

Вы можете избежать побега [ а также ] специальные символы, поскольку это не является неоднозначным для 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]

В частном случае 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 ]

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

Но вы можете сделать то же самое с этим шаблоном, немного оптимизированным, и более полезная причина, многократно используемая как subpattern (?-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)[^][]*)*+]) это позволяет избежать затрат на чередование.

Другие вопросы по тегам