2009-03-03 6 views
1

je le code suivant:python regex mal à

what = re.match("get|post|put|head\s+(\S+) ",data,re.IGNORECASE)

et dans les données variables Disons que j'ai cette ligne:

GET some-site.com HTTP/1.0 ...

Si j'arrête le script dans le débogueur, et inspecter le quelle variable, je peux le voir seulement apparié GET. Pourquoi ne correspond-il pas à some-site.com?

Répondre

3
 

>>> re.match("(get|post|put|head)\s+(\S+) ",'GET some-site.com HTTP/1.0 ...',re.IGNORECASE).groups() 
('GET', 'some-site.com') 
>>>                       
 
+0

Cela fonctionne, mais pouvez-vous s'il vous plaît expliquer pourquoi ma version ne fonctionne pas? Je veux seulement capturer le deuxième mot. Je sais que je peux y accéder en appelant .group (1), mais je suis perplexe quant à la raison pour laquelle ma version n'a pas fonctionné. – Geo

+0

"Pourquoi 1 + 2 + 3 + 4 * 100 est 406 et non 1000"? http://www.amk.ca/python/howto/regex/regex.html#SECTION000510000000000000000. Lisez à propos du "|" caractère et sa préséance. – tzot

4

La priorité des opérateurs de langage Regex place head\s+(\S+) comme 4e alternative. La parenthèse dans réponse @Mykola Kharechko organiser pour head comme la 4e alternative, et \s+(\S+) est ajouté à l'alternative qui correspond au groupe.

1

+1 La réponse de Mykola et l'explication de Gimel. En outre, voulez-vous vraiment utiliser regex pour cela? Comme vous l'avez découvert, ils ne sont pas aussi simples qu'ils le paraissent. Voici une méthode non-regex:

def splitandpad(s, find, limit): 
    seq= s.split(find, limit) 
    return seq+['']*(limit-len(seq)+1) 

method, path, protocol= splitandpad(data, ' ', 2) 
if method.lower() not in ('get', 'head', 'post', 'put'): 
    # complain, unknown method 
if protocol.lower() not in ('http/1.0', 'http/1.1'): 
    # complain, unknown protocol 
+0

Ouais, je sais que j'aurais pu utiliser split. J'ai commencé avec une regex, puis je me suis fâché que ça ne marche pas :) – Geo