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

StackOverflow https://stackoverflow.com/questions/3568995

Вопрос

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

"?(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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top