2013-05-08 289 views
1

我試圖匹配以下網址了幾個小時,似乎無法弄清楚和Im相當肯定它不是那麼困難:Python的URL匹配(正則表達式)

URL可以是這樣的:

/course/lesson-one/ 

,或者它也可以是:

/course/lesson-one/chapter-one/ 

什麼我是第二個URL匹配的情況如下:

/course/([a-zA-Z]+[-a-zA-Z]*)/([a-zA-Z]+[-a-zA-Z]*)/ 

我要的是第二部分是可選的,但我無法弄清楚我最接近的是以下幾點:由於某種原因離開了最後一個字母

/course/([a-zA-Z]+[-a-zA-Z]*)/*([a-zA-Z]+[-a-zA-Z]*)/ 

但上面這個詞,例如,如果該URL是

/course/computers/ 

我結束了字符串「計算機」

回答

1

您使用?如果需要選裝件。

/course/([a-zA-Z][-a-zA-Z]*)/([a-zA-Z][-a-zA-Z]*/)? 
#            ^

(注意[a-zA-Z]+[-a-zA-Z]*相當於[a-zA-Z][-a-zA-Z]*。)

使用一個附加分組(?:…)排除從匹配的/,同時允許多個元素是可選的,在一次:

/course/([a-zA-Z][-a-zA-Z]*)/(?:([a-zA-Z][-a-zA-Z]*)/)? 
#       ~~~      ~^ 

你的第二個正則表達式會吞下最後一個字符,因爲:

/course/([a-zA-Z]+[-a-zA-Z]*)/*([a-zA-Z]+[-a-zA-Z]*)/ 
      ^^^^^^^^^^^^^^^^^^^^^ ~~~~~~~~~~~~~~~~~~~~~ 
     this matches 'computer' and this matches the 's'. 

的第二組中的此正則表達式匹配由於+某些字母表與長度爲1或更需要的,所以「s」必須屬於那裏。

+0

好的,謝謝你,這是問號,即時通訊失蹤。只是瞥了一眼文檔,它的一行就解釋了爲什麼我忽略了它! – Tkingovr 2013-05-08 20:34:46

+0

上面包含的第二個正則表達式正是我所需要的,同時也非常感謝你對它的真正解釋+100。感謝下面提供的每個人。 – Tkingovr 2013-05-08 21:41:07

1

使用「?」之後使其成爲可選項。

>>> r = r"/course/([a-zA-Z]+[-a-zA-Z]*)(/[A-Z[a-z]+[-a-zA-Z]*)?" 
>>> s = "/course/lesson-one/chapter-one/" 
>>> re.match(r, s).groups() 
('lesson-one', '/chapter-one') 
>>> s = "/course/computers/" 
>>> re.match(r, s).groups() 
('computers', None) 
1

您可以使用以下正則表達式:

'/course/([a-zA-Z]+[-a-zA-Z]*)(/([a-zA-Z]+[-a-zA-Z]*)/)?' 

這使得第二部分可選的,仍然符合每個URL的部分。

注意,URL的第二部分有兩組:匹配chapter-one

>>> re.match('/course/([a-zA-Z]+[-a-zA-Z]*)(/([a-zA-Z]+[-a-zA-Z]*)/)?', '/course/lesson-one/chapter-one/').groups() 
('lesson-one', '/chapter-one/', 'chapter-one') 

同樣一個匹配/chapter-one/和一個:

>>> re.match('/course/([a-zA-Z]+[-a-zA-Z]*)(/([a-zA-Z]+[-a-zA-Z]*)/)?', '/course/lesson-one/').groups() 
('lesson-one', None, None)