Как написать регулярное выражение, соответствующее шаблону, который может содержать кавычки, но если это так, должно иметь соответствующие кавычки в начале и конце?
"?(pattern)"?
Не будет работать, потому что это позволит шаблонам, которые начинаются с кавычки, но не заканчиваются ею.
"(pattern)"|(pattern)
Будет работать, но повторяется. Есть ли лучший способ сделать это без повторения шаблона?
Вы можете получить решение без повторения, используя обратные ссылки и условные выражения :
/^(")?(pattern)(?(1)\1|)$/
Соответствует:
Не совпадает:
Однако этот шаблон несколько сложен. Сначала он ищет необязательную цитату и помещает ее в обратную ссылку 1, если она найдена. Затем он ищет ваш узор. Затем он использует условный синтаксис, чтобы сказать: «Если обратная ссылка 1 найдена снова, сопоставить ее, иначе ничего не сопоставить». Весь шаблон привязан к (что означает, что он должен появляться сам по себе в строке), так что несопоставленные кавычки не будут захвачены (в противном случае шаблон
в шаблоне »
будет соответствовать).
Обратите внимание, что поддержка условных выражений зависит от механизма, и более подробные, но повторяющиеся выражения будут поддерживаться более широко (и, вероятно, их легче понять).
Обновление: Гораздо более простой версией этого регулярного выражения будет / ^ (")? (Шаблон) \ 1 $ /
, для которого не требуется условное выражение. Когда я сначала тестировал это , тестер, который я использовал, дал мне ложноотрицательный результат, из-за чего я отказался от него (ой!).
Я оставлю решение с условием для потомков и интереса, но это более простая версия, которая больше вероятно, будет работать в более широком спектре движков (здесь используются только обратные ссылки, которые могут не поддерживаться).
Это должно работать с рекурсивным регулярным выражением (которое требует больше времени для правильного выполнения). А пока: в Perl вы можете создать самомодифицирующееся регулярное выражение . Я оставлю это как академический пример; -)
my @stuff = ( '"pattern"', 'pattern', 'pattern"', '"pattern' );
foreach (@stuff) {
print "$_ OK\n" if /^
(")?
\w+
(??{defined $1 ? '"' : ''})
$
/x
}
Результат:
"pattern" OK
pattern OK
В зависимости от используемого языка вы должны иметь возможность использовать обратные ссылки. Что-то вроде этого, скажем:
(["'])(pattern)\1|^(pattern)$
Таким образом, вы требуете, чтобы либо не было кавычек, либо чтобы на обоих концах использовалась ОДИНАКОВАЯ кавычка.