Различение слешей в строке с помощью регулярного выражения - PullRequest
6 голосов
/ 25 мая 2011

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

  1. A имя , соответствующее регулярному выражению \w*
  2. A вызов , соответствующий выражению \w*\(.*\)
  3. A путь , соответствующий выражению <.*>|\".*\". путь может содержать косую черту.

Пример строки может выглядеть следующим образом:

bar/foo()/foo(bar)/<foo/bar>/bar/"foo/bar"/foo()

, который имеет следующую структуру

name/call/call/path/name/path/call

Я хочу разбить эту строку на части, и я пытаюсь сделать это с помощью регулярного выражения. Мое текущее выражение фиксирует косые черты после вызовов и путей , но у меня возникают проблемы с получением, чтобы оно захватывало косые черты после имён , не включая также косые черты, которые могут существовать в путях , Мое текущее выражение, просто запись слешей после путей и вызовов выглядит следующим образом:

(?<=[\)>\"])/

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

Ответы [ 4 ]

3 голосов
/ 25 мая 2011

Если ваш разделитель для вашей строки не экранирован при использовании внутри вашего ввода, может быть не лучшим выбором.Тем не менее, у вас есть роскошь «ложной» косой черты, находящейся внутри обычного шаблона.Что я предлагаю ...

  1. Разбить всю строку на "/"
  2. Анализировать каждую часть, пока не дойдете до начала пути
  3. Поставить путьэлементы в списке до конца пути
  4. Вернитесь к пути назад на "/"

Я настоятельно рекомендую вам избегать использования "/" в ваших путях, чтобы сделать вашу жизньлегче.

3 голосов
/ 25 мая 2011
(\w+|\w+\([^/]*\)(?:/\w+\([^/]*\))*|<[^>]*>|"[^"]*")(?=/|$)

захватывает это из строки 'bar/foo()/foo(bar)/<foo/bar>/bar/"foo/bar"/foo()'

  • 'bar'
  • 'foo()/foo(bar)'
  • '<foo/bar>'
  • 'bar'
  • '"foo/bar"'
  • 'foo()'

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

Более простой (\w+|\w+\([^/]*\)|<[^>]*>|"[^"]*")(?=/|$) будет захватывать вызовы отдельно:

  • "foo()"
  • "foo(bar)"

РЕДАКТИРОВАТЬ: Обычно я делаю регулярное выражение:

(           # begin group 1 (for alternation)
  \w+       #   at least one word character
|           # or...
  \w+       #   at least one word character
  \(        #   a literal "("
  [^/]*     #   anything but a "/", as often as possible
  \)        #   a literal ")"
|           # or...
  <         #   a "<"
  [^>]*     #   anything but a ">", as often as possible
  >         #   a ">"
|           # or...
  "         #   a '"'
  [^"]*     #   anything but a '"', as often as possible
  "         #   a '"'
)           # end group 1
(?=/|$)     # look-ahead: ...followed by a slash or the end of string
3 голосов
/ 25 мая 2011

Моей первой мыслью было сопоставить косые черты с четным числом кавычек слева от него. (Т. Е. Положительный взгляд на что-то вроде (".*")*, но в итоге получается исключение, говорящее

Look-behind group does not have an obvious maximum length

Честно говоря, я думаю, что вам будет лучше с Matcher, использующим или: ed вместе версию ваших компонентов (что-то вроде \w*|\w*\(.*\)|(<.*>|\".*\")) и сделайте while (matcher.find()).

1 голос
/ 25 мая 2011

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

\w+\(.*?\)|<.*>|\".*\"|\w+
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...