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 .
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
)
"
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
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
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 () .
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'];
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
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
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
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
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
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
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 = "";
}
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