2011-11-29 6 views
10

Quale sarebbe la migliore espressione regolare per questo scenario?Abbina il percorso di un URL, meno l'estensione del nome file

Dato questo URL:

http://php.net/manual/en/function.preg-match.php 

Come dovrei andare sulla selezione di tutto tra (esclusi) e http://php.net.php:

/manual/en/function.preg-match 

questo è per un file di configurazione Nginx.

+0

'(?: Http: [\ /] {2}. +? [.]) [^ \ /] + (. +) [.] +. +' – gaussblurinc

risposta

7

Ti piace questa:

if (preg_match('/(?<=net).*(?=\.php)/', $subject, $regs)) { 
    $result = $regs[0]; 
} 

Spiegazione:

" 
(?<=  # Assert that the regex below can be matched, with the match ending at this position (positive lookbehind) 
    net  # Match the characters “net” literally 
) 
.   # Match any single character that is not a line break character 
    *   # Between zero and unlimited times, as many times as possible, giving back as needed (greedy) 
(?=  # Assert that the regex below can be matched, starting at this position (positive lookahead) 
    \.  # Match the character “.” literally 
    php  # Match the characters “php” literally 
) 
" 
+0

Grazie FailedDev per la spiegazione dettagliata, che funziona perfettamente – silkAdmin

+3

''/ net (. *) \. Php /'', versione più semplice, più breve (e probabilmente più performante) della stessa espressione. (Preferisco le espressioni senza inutili sguardi inutili.) – Qtax

2

Prova questo:

preg_match("/net(.*)\.php$/","http://php.net/manual/en/function.preg-match.php", $matches); 
echo $matches[1]; 
// prints /manual/en/function.preg-match 
0

Questa partita generale URL consente di selezionare parti di un URL:

if (preg_match('/\\b(?P<protocol>https?|ftp):\/\/(?P<domain>[-A-Z0-9.]+)(?P<file>\/[-A-Z0-9+&@#\/%=~_|!:,.;]*)?(?P<parameters>\\?[-A-Z0-9+&@#\/%=~_|!:,.;]*)?/i', $subject, $regs)) { 
    $result = $regs['file']; 
    //or you can append the $regs['parameters'] too 
} else { 
    $result = ""; 
} 
19

Un'espressione regolare potrebbe non essere lo strumento più efficace per questo lavoro.

Provare a utilizzare parse_url(), combinata con pathinfo():

$url  = 'http://php.net/manual/en/function.preg-match.php'; 
$path  = parse_url($url, PHP_URL_PATH); 
$pathinfo = pathinfo($path); 

echo $pathinfo['dirname'], '/', $pathinfo['filename']; 

Le uscite di codice di cui sopra:

/manual/en/function.preg-match
+0

Grazie a phoenix, funziona anche io, ma stavo cercando una soluzione per questo. – silkAdmin

+1

@silkAdmin Questo è curioso; perché la soluzione deve essere un'espressione regolare? –

+1

Scusa non avrei dovuto usare il tag PHP che mi confondeva, avevo bisogno della regex per un file di configurazione Nginx in cui la tua soluzione non è un'opzione – silkAdmin

-1

espressioni regolari per la corrispondenza tutto dopo "rete" e prima di ".php":

$pattern = "net([a-zA-Z0-9_]*)\.php"; 

Nell'espressione regolare precedente, è possibile trovare il gruppo di caratteri corrispondente racchiuso tra "()" è quello che stai cercando.

Spero sia utile.

+2

Questo non corrisponderà all'esempio dato, perché c'è un punto in esso: 'function.preg-match' – Toto

+0

Per non parlare che non corrisponde nemmeno alle barre. Inoltre, il regexp non è ancorato - il che probabilmente non causerà problemi (l'operatore '*' è avido di default), ma non è una buona pratica. –

2

Non è necessario utilizzare un'espressione regolare per analizzare un URL. PHP ha funzioni integrate per questo, pathinfo() e parse_url().

0

Ecco una soluzione regex migliore di quello che la maggior parte hanno fornito finora, se mi chiedete: http://regex101.com/r/nQ8rH5

 
/http:\/\/[^\/]+\K.*(?=\.[^.]+$)/i 
0

Semplice:

$url = "http://php.net/manual/en/function.preg-match.php"; 
preg_match("/http:\/\/php\.net(.+)\.php/", $url, $matches); 
echo $matches[1]; 

$matches[0] è l'URL completo, $matches[1] è la parte che volere.

Vedi te stesso: http://codepad.viper-7.com/hHmwI2

1

Solo per il gusto di farlo, qui ci sono due modi che non sono stati esplorati:

substr($url, strpos($s, '/', 8), -4) 

O:

substr($s, strpos($s, '/', 8), -strlen($s) + strrpos($s, '.')) 

basato sull'idea che Gli schemi HTTP http:// e https:// hanno al massimo 8 caratteri, quindi in genere è sufficiente trovare la prima barra dalla 9a posizione in poi. Se l'estensione è sempre .php, il primo codice funzionerà, altrimenti è richiesto l'altro.

Per una soluzione pura espressione regolare è possibile interrompere la stringa giù come questo:

~^(?:[^:/?#]+:)?(?://[^/?#]*)?([^?#]*)~ 
          ^

La porzione percorso sarebbe all'interno del gruppo prima memoria (cioè indice 1), indicato dalla ^ nella linea sotto l'espressione. Rimozione l'estensione può essere fatto utilizzando pathinfo():

$parts = pathinfo($matches[1]); 
echo $parts['dirname'] . '/' . $parts['filename']; 

È inoltre possibile modificare le espressioni a questa:

([^?#]*?)(?:\.[^?#]*)?(?:\?|$) 

Questa espressione non è molto ottimale, però, perché ha un po 'indietro il monitoraggio in esso. Alla fine vorrei andare per qualcosa di meno personalizzato:

$parts = pathinfo(parse_url($url, PHP_URL_PATH)); 
echo $parts['dirname'] . '/' . $parts['filename']; 
0

| (? < = \ w) /.+ (?. = \ \ W + $) |

  • selezionare tutto, dalla prima letterale '/' preceduto da
  • sguardo dietro una parola (\ w) carattere
  • fino seguita da uno sguardo in avanti
    • letterale '' assegnata da
    • una o più parole (\ w) caratteri
    • prima della fine $
 
    re> |(?<=\w)/.+(?=\.\w+$)| 
Compile time 0.0011 milliseconds 
Memory allocation (code space): 32 
    Study time 0.0002 milliseconds 
Capturing subpattern count = 0 
No options 
First char = '/' 
No need char 
Max lookbehind = 1 
Subject length lower bound = 2 
No set of starting bytes 
data> http://php.net/manual/en/function.preg-match.php 
Execute time 0.0007 milliseconds 
0: /manual/en/function.preg-match 

|. // [^ /] * (*). \ \ w + $ |

  • trovare due letterale '//' seguito da tutto tranne che un letterale '/'
  • selezionare tutto fino
  • trovare letterale '' seguito da solo Word \ w caratteri prima della fine $
 
    re> |//[^/]*(.*)\.\w+$| 
Compile time 0.0010 milliseconds 
Memory allocation (code space): 28 
    Study time 0.0002 milliseconds 
Capturing subpattern count = 1 
No options 
First char = '/' 
Need char = '.' 
Subject length lower bound = 4 
No set of starting bytes 
data> http://php.net/manual/en/function.preg-match.php 
Execute time 0.0005 milliseconds 
0: //php.net/manual/en/function.preg-match.php 
1: /manual/en/function.preg-match 

|/[^ /] + (. *) \.|

  • trovare letterale '/' seguita da almeno 1 o più non letterale '/'
  • aggressivo selezionare tutto prima dell'ultimo letterale ''
 
    re> |/[^/]+(.*)\.| 
Compile time 0.0008 milliseconds 
Memory allocation (code space): 23 
    Study time 0.0002 milliseconds 
Capturing subpattern count = 1 
No options 
First char = '/' 
Need char = '.' 
Subject length lower bound = 3 
No set of starting bytes 
data> http://php.net/manual/en/function.preg-match.php 
Execute time 0.0005 milliseconds 
0: /php.net/manual/en/function.preg-match. 
1: /manual/en/function.preg-match 

|/[^ /] + \ K * (= \?.). |

  • trovare letterale '/' seguita da almeno 1 o più non letterale '/'
  • Ripristina Selezionare Start \ K
  • aggressivo selezionare tutto prima
  • guardare avanti ultima letterale ''
 
    re> |/[^/]+\K.*(?=\.)| 
Compile time 0.0009 milliseconds 
Memory allocation (code space): 22 
    Study time 0.0002 milliseconds 
Capturing subpattern count = 0 
No options 
First char = '/' 
No need char 
Subject length lower bound = 2 
No set of starting bytes 
data> http://php.net/manual/en/function.preg-match.php 
Execute time 0.0005 milliseconds 
0: /manual/en/function.preg-match 

| \ w + \ K /.* (= \?.) |

  • trovare una o più parole (\ w) caratteri prima di un letterale '/'
  • ripristino selezionare Start \ K
  • selezionare letterale '/' seguita da
  • nulla prima
  • guardare avanti ultimo letterale '.'
 
    re> |\w+\K/.*(?=\.)| 
Compile time 0.0009 milliseconds 
Memory allocation (code space): 22 
    Study time 0.0003 milliseconds 
Capturing subpattern count = 0 
No options 
No first char 
Need char = '/' 
Subject length lower bound = 2 
Starting byte set: 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P 
    Q R S T U V W X Y Z _ a b c d e f g h i j k l m n o p q r s t u v w x y z 
data> http://php.net/manual/en/function.preg-match.php 
Execute time 0.0011 milliseconds 
0: /manual/en/function.preg-match 
-1

http:[\/]{2}.+?[.][^\/]+(.+)[.].+

vediamo, ciò che fatto:

http:[\/]{2}.+?[.][^\/] - gruppo non-acquisizione per http://php.net

(.+)[.] - cattura parte fino all'ultimo punto si verificano: /manual/en/function.preg-match

[.].+ - estensione corrispondente di file come questo: .php

Problemi correlati