Попытка сопоставить то, что находится до /../, но после / с регулярными выражениями - PullRequest
2 голосов
/ 13 апреля 2010

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

Я чувствую, что я близко, но он просто смотрит на первую косую черту, а затем берет все после этого, как ... входные данные это:

this/is/a/./path/that/../includes/face/./stuff/../hat

и мое регулярное выражение:

#\/(.*)\.\.\/#

соответствует /is/a/./path/that/../includes/face/./stuff/../ вместо that/../ и stuff/../

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

Ответы [ 7 ]

2 голосов
/ 13 апреля 2010

.* означает «соответствовать любому числу любого символа вообще [1]». Это не то, что вы хотите. Вы хотите сопоставить любое количество не - / символов, которое написано [^/]*.

Каждый раз, когда у вас возникает желание использовать .* или .+ в регулярном выражении, будьте очень подозрительны. Остановитесь и спросите себя, действительно ли вы имеете в виду «любой персонаж вообще [1]» или нет - в большинстве случаев вы этого не делаете. (И да, не жадные квантификаторы могут помочь с этим, но классы символов более эффективны для сопоставления движку регулярных выражений и более ясны в сообщении ваших намерений читателям-людям.)

[1] ОК, ОК ... . не совсем "любой символ вообще" - он не соответствует переводу строки (\n) по умолчанию в большинстве разновидностей регулярных выражений - но достаточно близко.

1 голос
/ 13 апреля 2010

Кроме того, вы можете использовать lookahead .

#(\w+)(?=/\.\./)#

Объяснение

NODE                     EXPLANATION
--------------------------------------------------------------------------------
  (                        group and capture to \1:
--------------------------------------------------------------------------------
    \w+                      word characters (a-z, A-Z, 0-9, _) (1 or
                             more times (matching the most amount
                             possible))
--------------------------------------------------------------------------------
  )                        end of \1
--------------------------------------------------------------------------------
  (?=                      look ahead to see if there is:
--------------------------------------------------------------------------------
    /                        '/'
--------------------------------------------------------------------------------
    \.                       '.'
--------------------------------------------------------------------------------
    \.                       '.'
--------------------------------------------------------------------------------
    /                        '/'
--------------------------------------------------------------------------------
  )                        end of look-ahead
1 голос
/ 13 апреля 2010

Измените ваш шаблон, чтобы сопоставлялись только символы, отличные от / ([^/]):

#([^/]*)/\.\./#
0 голосов
/ 13 апреля 2010

([^/]+) захватит весь текст между слешами.

([^/]+)*/\.\. соответствует that\.. и stuff\.. в вашей строке this/is/a/./path/that/../includes/face/./stuff/../hat Он захватывает that или stuff, и вы можете изменить это, очевидно, изменив расположение захватывающих паренов и логику вашей программы ,

Вы не указали, хотите ли вы захватить или просто сопоставить. Здесь регулярное выражение будет захватывать только это последнее совпадение (материал), но его легко изменить, чтобы оно возвращало that затем stuff, если используется глобально в глобальном совпадении.

NODE                     EXPLANATION
--------------------------------------------------------------------------------
  (                        group and capture to \1 (0 or more times
                           (matching the most amount possible)):
--------------------------------------------------------------------------------
    [^/]+                    any character except: '/' (1 or more
                             times (matching the most amount
                             possible))
--------------------------------------------------------------------------------
  )*                       end of \1 (NOTE: because you're using a
                           quantifier on this capture, only the LAST
                           repetition of the captured pattern will be
                           stored in \1)
--------------------------------------------------------------------------------
  /                        '/'
--------------------------------------------------------------------------------
  \.                       '.'
--------------------------------------------------------------------------------
  \.                       '.'
0 голосов
/ 13 апреля 2010

В питоне:

>>> test = 'this/is/a/./path/that/../includes/face/./stuff/../hat'
>>> regex = re.compile(r'/\w+?/\.\./')
>>> regex.findall(me)
['/that/..', '/stuff/..']

Или, если вы просто хотите текст без косой черты:

>>> regex = re.compile(r'/(\w+?)/\.\./')
>>> regex.findall(me)
['that', 'stuff']
0 голосов
/ 13 апреля 2010

На вашем любимом языке сделайте несколько разбиений и манипуляций со строками, например, Python

>>> s="this/is/a/./path/that/../includes/face/./stuff/../hat"
>>> a=s.split("/../")[:-1]  # the last item is not required.
>>> for item in a:
...   print item.split("/")[-1]
...
that
stuff
0 голосов
/ 13 апреля 2010

Я думаю, что вы по существу правы, вам просто нужно сделать совпадение не жадным, или изменить (.*), чтобы не допустить косую черту: #/([^/]*)/\.\./#

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