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