Регулярное выражение: используйте начало / конец строки (^ или $) в другом контексте - PullRequest
52 голосов
/ 31 марта 2010

Выполняя небольшую задачу регулярного выражения, я столкнулся с этой проблемой. У меня есть строка, которая представляет собой список тегов, который выглядит, например, так:
foo,bar,qux,garp,wobble,thud

Что мне нужно было сделать, это проверить, есть ли определенный тег, например, 'garp' был в этом списке. (То, что он в конце концов соответствует, не очень важно, просто есть совпадение или нет.)

Моей первой и немного глупой попыткой было использовать следующее регулярное выражение:
[^,]garp[,$]

Моя идея заключалась в том, что перед 'garp' должно быть либо начало строки / строки, либо запятая, после 'garp' должна быть либо запятая, либо конец строки / строки.

Теперь очевидно, что это регулярное выражение неверно: и ^, и $ изменяют свое поведение в контексте класса символов [].

Я наконец-то придумал следующее:
^garp$|^garp,|,garp,|,garp$

Это регулярное выражение обрабатывает 4 случая один за другим. (Пометьте в начале списка, в центре, в конце или как единственный элемент списка.) Последнее регулярное выражение как-то немного уродливо в моих глазах, и просто ради интереса, я бы хотел сделать это немного более элегантный.

Есть ли способ использовать символы начала и конца строки (^ и $) в контексте классов символов?

EDIT: Хорошо, пожелали еще немного информации, так что вот оно: Я использую это в инструкции Oracle SQL. Это, к сожалению, не допускает каких-либо проверок, но поскольку меня интересует только совпадение или нет (а не то, что сопоставляется), это на самом деле не влияет на меня. Теги могут содержать не алфавитные символы, такие как - или _, поэтому \ bgarp \ b не будет работать. Также один тег может содержать другой тег, как сказал SilentGhost, поэтому / garp / тоже не работает.

Ответы [ 5 ]

79 голосов
/ 31 марта 2010

Вы не можете использовать ^ и $ в классах символов так, как вам нравится - они будут интерпретироваться буквально, но вы можете использовать чередование для достижения того же эффекта:

(^|,)garp(,|$)
22 голосов
/ 31 марта 2010

вам просто нужно использовать границу слова (\b) вместо ^ и $:

\bgarp\b
5 голосов
/ 31 марта 2010

Просто используйте осмотры, чтобы решить это:

(?<=^|,)garp(?=$|,)

Разница между осмотрами и обычными группами заключается в том, что в обычных группах запятая будет частью матча, а при осмотрах - нет. В этом случае это не имеет значения, хотя.

3 голосов
/ 31 марта 2010

Я большой поклонник регулярных выражений, но в этом случае (строка, разделенная запятыми), хотя оба решения Марка Байерса, SilentGhost и reko_t работают, я бы скорее предложил посмотреть на анализатор CSV.

Может быть, это излишне для этой работы, но тогда мы не знаем реальных требований и реальных данных, которые необходимо обработать.

1 голос
/ 19 января 2016

Это можно было бы немного оптимизировать с помощью функции SQL INSTR (позиция строки), для этого не требуется регулярное выражение.

Просто проверьте, если / или:

  1. Если строка равна garp (единственный элемент в списке)
  2. Если garp, находится в позиции 1 (то есть в позиции 0) строки (первый элемент в списке)
  3. Если ,garp находится на позиции LENGTH(string) - LENGTH(',garp') [1] (последний элемент в списке)
  4. Если строка содержит ,garp, вообще (в середине списка)

[1] Возможно, здесь смещается одна ошибка

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...