web-dev-qa-db-fra.com

Correspond au chemin d'accès d'une URL, moins l'extension du nom de fichier

Quelle serait la meilleure expression régulière pour ce scénario?

Étant donné cette URL:

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

Comment dois-je procéder pour tout sélectionner entre (mais non compris) http://php.net et .php:

/manual/en/function.preg-match

Ceci est pour un fichier de configuration Nginx .

11
silkAdmin

Comme ça:

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

Explication:

"
(?<=      # 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
)
"
8
FailedDev

Une expression régulière peut ne pas être l'outil le plus efficace pour ce travail.

Essayez d’utiliser parse_url() , combiné avec 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 code ci-dessus renvoie:

/manual/en/function.preg-match
20
user212218

Essaye ça:

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

Il n'est pas nécessaire d'utiliser une expression régulière pour disséquer une URL. PHP a des fonctions intégrées pour cela, pathinfo () et parse_url () .

3
Crayon Violent

Juste pour le plaisir, voici deux manières qui n’ont pas été explorées:

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

Ou:

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

Basé sur l'idée que les schémas HTTP http:// Et https:// Sont au maximum de 8 caractères, il suffit donc généralement de trouver la première barre oblique à partir de la 9ème position. Si l'extension est toujours .php, Le premier code fonctionnera, sinon l'autre est requis.

Pour une solution d'expression régulière pure, vous pouvez décomposer la chaîne comme suit:

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

La portion de chemin se trouverait dans le premier groupe de mémoire (c'est-à-dire l'index 1), indiqué par le symbole ^ Dans la ligne située sous l'expression. La suppression de l'extension peut être effectuée à l'aide de pathinfo():

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

Vous pouvez également modifier l'expression à ceci:

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

Cette expression n’est cependant pas très optimale, car elle contient un certain suivi. En fin de compte, je choisirais quelque chose de moins personnalisé:

$parts = pathinfo(parse_url($url, PHP_URL_PATH));
echo $parts['dirname'] . '/' . $parts['filename'];
2
Ja͢ck

Facile:

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

$matches[0] est votre URL complète, $matches[1] est la partie que vous voulez.

Voyez-vous: http://codepad.viper-7.com/hHmwI2

0
user1626664

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

  • sélectionner tout du premier littéral '/' précédé de
  • regarder derrière un caractère Word (\ w)
  • jusqu'à ce que suivi d'un regard à venir
    • littéral '.' annexé par
    • un ou plusieurs caractères Word (\ w)
    • avant la fin $
 re> | (? <=\w)/.+ (? = \.\w + $) | 
 Temps de compilation 0.0011 millisecondes 
 Allocation de mémoire (espace de code): 32 
 Temps d'étude 0,0002 milliseconde 
 Capture du nombre de sous-modèles = 0 
 Pas d'options 
 Premier caractère = '/'
Non besoin de caractère 
 Max lookbehind = 1 
 Limite inférieure de la longueur du sujet = 2 
 Aucun ensemble d'octets de début 
 Data> http://php.net/manual/en/function.preg-match. php 
 temps d'exécution 0,0007 millisecondes 
 0: /manual/en/function.preg-match

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

  • trouve deux '//' littéraux suivis de tout sauf d'un '/' littéral
  • tout sélectionner jusqu'à
  • trouver littéralement '.' suivi de Word\w caractères avant la fin $
 re> | // [^ /] * (. *) \.\w + $ | 
 Temps de compilation 0.0010 millisecondes 
 Allocation de mémoire (espace de code): 28 
 Temps d'étude 0,0002 millisecondes 
 Capture du nombre de sous-modèles = 1 
 Pas d'options 
 Premier caractère = '/'
Need char ='. '
 Limite inférieure de la longueur du sujet = 4 
 Pas d’octets de départ 
 Données> http://php.net/manual/en/function.preg-match.php
Execute time 0.0005 millisecondes 
 0: //php.net/manual/fr/function.preg-match.php
 1: /manual/fr/function.preg-match

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

  • trouve le littéral '/' suivi d'au moins un ou plusieurs non littéraux '/'
  • agressif sélectionner tout avant le dernier littéral '.'
 re> |/[^ /] + (. *) \. | 
 Temps de compilation 0,0008 milliseconde 
 Allocation de mémoire (espace de code): 23 
 Temps d'étude 0,0002 milliseconds 
 Capture du nombre de sous-modèles = 1 
 Pas d’option 
 Premier caractère = '/'[.____. He'sNeed ='. '
 Limite inférieure de longueur du sujet = 3 
 Pas d’octets de départ 
 Données> http://php.net/manual/en/function.preg-match.php
.exécutez le temps 0,0005 milliseconds 
 0: /php.net/manual/en/function.preg-match.
 1: /manual/en/function.preg-match

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

  • trouve le littéral '/' suivi d'au moins un ou plusieurs non littéraux '/'
  • Réinitialiser sélectionner démarrer\K
  • agressif tout sélectionner avant
  • regarder devant soi dernier littéral '.'
 re> |/[^ /] +\K. * (? = \.) | 
 Temps de compilation 0,0009 milliseconds 
 Allocation de mémoire (espace de code): 22 
 Temps d'étude 0,0002 millisecondes 
 Capture du nombre de sous-modèles = 0 
 Pas d'options 
 Premier caractère = '/'
Pas besoin de caractère 
 Longueur du sujet inférieure bound = 2 
 Pas d'octets de départ 
 données> http://php.net/manual/en/function.preg-match.php
.exécutez le temps 0,0005 milliseconds 
 0: /manual/en/function.preg-match

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

  • trouve un ou plusieurs caractères Word (\ w) avant un '/' littéral
  • réinitialiser sélectionnez démarrer\K
  • sélectionnez littéralement '/' suivi de
  • quoi que ce soit avant
  • regarder devant soi dernier littéral '.'
 re> |\w +\K /.* (? = \.) | 
 Temps de compilation 0,0009 milliseconds 
 Allocation de mémoire (espace de code): 22 
 Étude temps 0,0003 milliseconds 
 Capture du nombre de sous-modèles = 0 
 Pas d'options 
 Pas de premier caractère 
 Besoin char = '/[.____. Page_Longueur du sujet inférieure = 2 
 Ensemble d'octets de départ: 0 1 2 3 4 5 6 7 8 9 ABCDEFGHIJKLMNOP 
 QRSTUVWXYZ _ abcdefghijklmnopqrstu vwxyz 
 Data> http://php.net/manual/en/function. preg-match.php 
 temps d'exécution 0.0011 millisecondes 
 0: /manual/en/function.preg-match
0
nickl-

Cette correspondance d'URL générale vous permet de sélectionner des parties d'une 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 = "";
}
0
Homer6

Voici une solution regex meilleure que celle fournie par la plupart des utilisateurs jusqu'à présent, si vous me demandez: http://regex101.com/r/nQ8rH5

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