Соответствие пути URL-адреса, за вычетом расширения имени файла
Какое будет лучшее регулярное выражение для этого сценария?
С учетом этого URL-адреса:
http://php.net/manual/en/function.preg-match.php
Как мне выбрать выбор между (но не включая) http://php.net
и .php
:
/manual/en/function.preg-match
Это для конфигурационного файла Nginx.
Ответы
Ответ 1
Вот так:
if (preg_match('/(?<=net).*(?=\.php)/', $subject, $regs)) {
$result = $regs[0];
}
Пояснение:
"
(?<= # 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
)
"
Ответ 2
Регулярное выражение может быть не самым эффективным инструментом для этого задания.
Попробуйте использовать parse_url()
в сочетании с 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'];
Вышеупомянутый код выводит:
/manual/en/function.preg-match
Ответ 3
Попробуйте следующее:
preg_match("/net(.*)\.php$/","http://php.net/manual/en/function.preg-match.php", $matches);
echo $matches[1];
// prints /manual/en/function.preg-match
Ответ 4
Нет необходимости использовать регулярное выражение для анализа URL-адреса. PHP имеет встроенные функции для этого, pathinfo() и parse_url().
Ответ 5
Просто для удовольствия, вот два способа, которые не были изучены:
substr($url, strpos($s, '/', 8), -4)
Или:
substr($s, strpos($s, '/', 8), -strlen($s) + strrpos($s, '.'))
Основываясь на идее, что схемы HTTP http://
и https://
не более 8 символов, обычно обычно нужно найти первую косую черту с 9-й позиции. Если расширение всегда .php
, первый код будет работать, в противном случае требуется другое.
Для чистого решения регулярного выражения вы можете сломать строку так:
~^(?:[^:/?#]+:)?(?://[^/?#]*)?([^?#]*)~
^
Часть пути будет находиться внутри первой группы памяти (то есть индекса 1), обозначенной символом ^
в строке под выражением. Удаление расширения можно выполнить с помощью pathinfo()
:
$parts = pathinfo($matches[1]);
echo $parts['dirname'] . '/' . $parts['filename'];
Вы также можете настроить выражение следующим образом:
([^?#]*?)(?:\.[^?#]*)?(?:\?|$)
Это выражение не очень оптимально, потому что оно имеет в нем некоторое обратное отслеживание. В конце концов я бы пошел на что-то менее обыденное:
$parts = pathinfo(parse_url($url, PHP_URL_PATH));
echo $parts['dirname'] . '/' . $parts['filename'];
Ответ 6
Это общее совпадение URL-адресов позволяет вам выбирать части 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 = "";
}
Ответ 7
Здесь решение регулярных выражений лучше, чем большинство из них до сих пор, если вы спросите меня: http://regex101.com/r/nQ8rH5
/http:\/\/[^\/]+\K.*(?=\.[^.]+$)/i
Ответ 8
Простой:
$url = "http://php.net/manual/en/function.preg-match.php";
preg_match("/http:\/\/php\.net(.+)\.php/", $url, $matches);
echo $matches[1];
$matches[0]
- ваш полный URL, $matches[1]
- это часть, которую вы хотите.
Посмотрите сами: http://codepad.viper-7.com/hHmwI2
Ответ 9
| (? & Л; =\ш)/.+ (?. =\\ Ш + $) |
- выберите все из первого литерала '/', которому предшествует
- смотреть за символом Word (\ w)
- до следующего обзора
- literal '.' добавлено
- один или несколько символов Word (\ w)
- до конца $
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
|//[^/] *\\ ш + $(. *) |.
- найдите два литерала '//', за которым следует что-либо, кроме буквального '/'
- выберите все, пока
- найти литерал '.' за которым следуют только символы Word\w до конца $
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
|/[^/] +\(*.) |.
- найдите литерал '/', за которым следует хотя бы 1 или более нелитературный '/'
- агрессивный выбор всего до последнего литерала '.
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
|/[^/] +\К * (= \?.) |.
- найдите литерал '/', за которым следует хотя бы 1 или более нелитературный '/'
- Reset выберите start\K
- агрессивный выбор всего до
- Посмотрите вперед последний литерал '.'
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
|\ш +\К/.* (= \?.) |
- найдите один или несколько символов Word (\ w) перед литералом '/'
- Reset выберите start\K
- выберите литерал '/', а затем
- ничего перед
- Посмотрите вперед последний литерал '.'
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
Ответ 10
Регулярное выражение для сопоставления всего после "net" и перед ".php":
$pattern = "net([a-zA-Z0-9_]*)\.php";
В приведенном выше регулярном выражении вы можете найти подходящую группу символов, заключенных в()(), чтобы быть тем, что вы ищете.
Надеюсь, что это полезно.
Ответ 11
http:[\/]{2}.+?[.][^\/]+(.+)[.].+
посмотрим, что он сделал:
http:[\/]{2}.+?[.][^\/]
- группа без захвата для http://php.net
(.+)[.]
- захватить часть до последней точки: /manual/en/function.preg-match
[.].+
- сопоставление расширения файла следующим образом: .php