Подтвердить что ты не робот

Как сопоставить шаблон с дополнительными кавычками?

Как написать регулярное выражение, которое соответствует шаблону, который может содержать кавычки, но если это так, должны иметь соответствующие кавычки в начале и конце?

"?(pattern)"?

Не будет работать, потому что это позволит шаблонам, начинающимся с цитаты, но не заканчивающимся одним.

"(pattern)"|(pattern)

Будет работать, но повторяется. Есть ли лучший способ сделать это без повторения шаблона?

4b9b3361

Ответ 1

Вы можете получить решение без повторения, используя обратные ссылки и условный:

/^(")?(pattern)(?(1)\1|)$/

Матчи:

  • шаблон
  • "шаблон"

Не соответствует:

  • "шаблон
  • шаблон "

Этот шаблон несколько сложный. Сначала он ищет необязательную цитату и помещает ее в backreference 1, если ее можно найти. Затем он ищет ваш шаблон. Затем он использует условный синтаксис, чтобы сказать "если backreference 1 найден снова, сопоставьте его, иначе ничего не получится". Весь шаблон anchored (что означает, что он должен появиться сам по себе на линии), так что непревзойденные кавычки не будут захвачены (в противном случае pattern в pattern" будет соответствовать).

Обратите внимание, что поддержка условных обозначений зависит от движка, и более подробные, но повторяющиеся выражения будут более широко поддерживаться (и, вероятно, легче понять).


Обновление:. Более простая версия этого регулярного выражения будет /^(")?(pattern)\1$/, которая не нуждается в условном выражении. Когда я тестировал это изначально, тестер, который я использовал, дал мне ложный отрицательный результат, который заставил меня отказаться от него (oops!).

Я оставлю решение с условием для потомков и интереса, но это более простая версия, которая с большей вероятностью будет работать в более широком диапазоне движков (обратные ссылки - единственная функция, используемая здесь, которая может быть неподдерживаемой).

Ответ 2

В зависимости от языка, который вы используете, вы можете использовать обратные ссылки. Что-то вроде этого, скажем:

(["'])(pattern)\1|^(pattern)$

Таким образом, вы требуете, чтобы либо нет кавычек, либо что ТОЛЬКО котировка используется на обоих концах.

Ответ 3

Это должно работать с рекурсивным регулярным выражением (для этого требуется больше времени). Тем временем: в Perl вы можете создать самомодифицирующееся регулярное выражение. Я оставлю это в качестве академического примера; -)

my @stuff = ( '"pattern"', 'pattern', 'pattern"', '"pattern'  );

foreach (@stuff) {
   print "$_ OK\n" if /^
                        (")?
                        \w+
                        (??{defined $1 ? '"' : ''})
                       $
                      /x
}

Результат:

"pattern" OK
pattern OK