Войти

Показать полную графическую версию : [решено] Распределить ссылки


Страниц : [1] 2

ateka
10-09-2020, 23:42
Здравствуйте, пытаюсь решить задачу но не знаю как.
На вход скрипта приходят URL трёх видов:
https://site.com/user/anything/anything
https://anything.site.com/anything-anything-12345678/anything
https://anything.site.com/
Из первого мне нужен только user
Из второго только цифры (они всегда разные)
Из третьего только субдомейн (в данном случае anything)
это я знаю как сделать.
После в каждом конкретном случае мне нужно сформировать URL и открыть в браузере.
И тут у меня ступор. Каким образом решаются подобные задачи?
Как сделать так что бы скрипт различал что это ссылка на пользователя, пост или субдомейн
и запускал на исполнение соответствующую сабрутину?
Заранее благодарю.

Foreigner
11-09-2020, 00:47
PowerShell:


$urls = 'https://site.com/user/anything/anything',
'https://anything.site.com/anything-anything-12345678/anything',
'https://anything.site.com/'

$user, $post, $sub = $urls -replace '.+//[^./]+\.[^/]+/([^/]+)/.+','$1' -replace '\D+(\d+)/.+','$1'

$user
$post
$sub

Fors1k
11-09-2020, 02:28
Foreigner, У меня не сработало:
user
anything-anything-12345678
https://anything.site.com/

$urls = 'https://site.com/user/anything/anything',
'https://anything.site.com/anything-anything-12345678/anything',
'https://anything.site.com/'
cls
$user = ($urls|sls "(?<=(?<!\..+)\.[^\.]+?/)[^/]+(?!.*-\d/)").Matches.Value
$sub = ($urls|sls "[^/]+?(?=\.(?=.+\.)[^/]+/$)").Matches.Value
$post = ($urls|sls "(?<=-)\d+").Matches.Value

"https://$sub.site.com/$user/$post"
Адова регулярка (с) DJ Mogarych, но на ночь глядя ничего красивее не стал искать)

Foreigner
11-09-2020, 07:23
У меня не сработало »
Это я перепутал вариант:

$urls = 'https://site.com/user/anything/anything',
'https://anything.site.com/anything-anything-12345678/anything',
'https://anything.site.com/'

$user, $post, $sub = $urls -replace '.+//[^./]+\.[^/]+/([^/]+)/.+','$1' `
-replace '\D+(\d+)','$1' `
-replace '.+//([^./]+).+', '$1'

"https://$sub/$user/$post"

Vadikan
11-09-2020, 08:44
PowerShell
В данном случае в качестве альтернативы регулярному выражению можно использовать оператор -Split - это попроще для непосвященных кмк (по кр. мере на простых примерах, объяснял тут http://www.outsidethebox.ms/19453/).

$urls = 'https://site.com/user/anything/anything',
'https://anything.site.com/anything-anything-12345678/anything',
'https://anything.site.com/'

$user = $urls[0].split('/')[3]
$post = ($urls[1].split('/')[3]).split('-')[2]
$sub = ($urls[2].split('/')[2]).split('.')[0]
"https://$sub.site.com/$user/$post"

Fors1k
11-09-2020, 10:42
можно использовать оператор -Split »
Как сделать так что бы скрипт различал что это ссылка на пользователя, пост или субдомейн »
Split конечно проще, но автор не знает как отличить ссылки друг от друга. Это говорит о том, что порядок ссылок заранее не известен.
Foreigner, тоже не сработает для другого порядка.

ateka
11-09-2020, 11:23
Друзья, я дико извиняюсь что был неясен и ввёл вас в заблуждение. Просто эта задача сломала мне остатки мозга. На вход скрипта приходит одного из трёх видов. И в зависимости от вида url я его обрабатываю нужным образом.

if _url==https://site.com/user/anything/anything goto usercheck
else
if _url==https://anything.site.com/anything-anything-12345678/anything goto postcheck
else
if _url==https://anything.site.com/ goto subdomaincheck
else goto error

За регулярки огромное спасибо я как раз думал в эту сторону но сам не осилил.

Foreigner
11-09-2020, 11:50
тоже не сработает для другого порядка. »

Возможно, Select-String тогда полезен, хоть и надо тестировать в любом случае. С урлами выкрутасы еще те.

Fors1k
11-09-2020, 12:34
На вход скрипта приходит одного из трёх видов »
$urls = (
'https://site.com/user/anything/anything',
'https://anything.site.com/anything-anything-12345678/anything',
'https://anything.site.com/'
)|Get-Random;cls


$search = @{
postID = "(?<=-)\d+"
userID = "(?<=(?<!\..+)\.\w+?/)[^/]+"
subDomain = "[^/]+?(?=\.(?=.+\.)[^/]+/$)"
}
$search.keys|%{
if($i=($urls|SLS $search[$_]).Matches.Value){
nv $_ $i -F;"В ссылке было:";gv $_|ft -hi
}
}

megaloman
11-09-2020, 16:00
На вход скрипта приходит одного из трёх видов. И в зависимости от вида url я его обрабатываю нужным образом. »
@Echo Off
cls
Set "URL=https://site.com/user/anything/anything"
Call :DefOut "%URL%" "Log" "Out"
Call :Sub%Log% "%URL%" "%Log%" "%Out%"

Set "URL=https://anything.site.com/anything-anything-12345678/anything"
Call :DefOut "%URL%" "Log" "Out"
Call :Sub%Log% "%URL%" "%Log%" "%Out%"

Set "URL=https://anything.site.com/"
Call :DefOut "%URL%" "Log" "Out"
Call :Sub%Log% "%URL%" "%Log%" "%Out%"
pause
Exit /B

:Sub1
Echo =======
Echo Вариант %2: user
Echo %1
Echo %3
Echo.
Exit /B

:Sub2
Echo =======
Echo Вариант %2: Цифры
Echo %1
Echo %3
Echo.
Exit /B

:Sub3
Echo =======
Echo Вариант %2: Субдомен
Echo %1
Echo %3
Echo.
Exit /B

:DefOut
SetLocal
Set "In=%~1"
Set "In=%In:*//=%"
Set "Reg=-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]"

FOR /F "tokens=1,2 delims=/" %%s IN ("%In%") DO (
If "%%t"=="" (
FOR /F "tokens=1 delims=." %%a IN ("%In%") DO (
EndLocal &(Set /A %~2=3 &Set "%~3=%%a" &Exit /B 3)
)
)
Set "In2=%%t"
Call Set "In2=%%In2:~-9%%"
Echo %%t|findstr /E /R /C:"%Reg%">nul||(
EndLocal &(Set /A %~2=1 &Set "%~3=%%t" &Exit /B 1)
)
)
Echo %In2%|findstr /E /R /C:"%Reg%">nul&&EndLocal &(Set /A %~2=2 &Set "%~3=%In2:~-8%" &Exit /B 2)
EndLocal &(Set /A %~2=0 &Set "%~3=" &Exit /B 0)
Exit /B

Vadikan
11-09-2020, 17:28
но автор не знает как отличить ссылки друг от друг »
Перечитал исходный пост - да, неправильно понял:)

greg zakharov
11-09-2020, 17:29
Ответ на оригинальный вопрос.[Uri[]]$u = 'https://site.com/user/anything/anything','https://anything.site.com/anything-anything-12345678/anything','https://anything.site.com/'
"https://$(($$ = $u[2].Host).Substring(0, $$.IndexOf('.'))).site.com/$(-join$u[0,1].ForEach{$_.Segments[1].Split('-')[-1]})"
Что касается сценариев разбора, если количество сегментов в URL всегда фиксировано:
[Uri[]]$u = 'https://site.com/user/anything/anything','https://anything.site.com/anything-anything-12345678/anything','https://anything.site.com'
# массив сценариев (скрипт-блоков), что нужно сделать в том или ином случае
$scenario = {'subdomaincheck'},{},{'postcheck'},{'usercheck'}
$u.ForEach{$scenario[$_.Segments.Count - 1]}
Если же количество сегментов URL не является постоянной величиной, но при этом сохраняются позиции указанных опорных точек (и их формат), можно нарисовать примерно следующую функцию:
#requires -version 7
function Get-UrlType {
[CmdletBinding(DefaultParameterSetName='Url')]
param(
[Parameter(Mandatory, ParameterSetName='Url', Position=0)]
[ValidateNotNullOrEmpty()]
[Uri[]]$Url,

[Parameter(Mandatory, ParameterSetName='Raw', Position=0)]
[ValidateNotNullOrEmpty()]
[String[]]$Raw
)

end {
$scope = $PSCmdlet.ParameterSetName -eq 'Raw' ? [Uri[]]$Raw : $Url
$scope.ForEach{
$_.Host.Split('.').Count -eq 2 ? $(
'User: {0}' -f $_.Segments[1].Trim('/')
) : $(
$_.Segments.Count -eq 1 ? $(
'Subdomain: {0}' -f $_.Host.Substring(0, $_.Host.IndexOf('.'))
) : $(
'Code: {0}' -f $_.Segments[1].Split([Char[]]@('-', '/'))[-2]
)
)
} # foreach
}
}
Вне зависимости от того, передаётся ли в функцию массив URI или просто строк, функция будет обрабатывать поступающие на вход данные как URI. В цикле для каждого элемента массива, передаваемого функции, выстраивается следующая логика:
1) если хост назначения состоит из двух элементов (вида site.com), следовательно в данном URL ищем юзера
2) в противном случае, если количество сегментов - единица, искать субдомен
3) иначе вытащить из второго сегмента URL цифровое значение
Таким образом:
$u = 'https://site.com/user/anything/anything',
'https://anything.site.com/anything-anything-12345678/anything',
'https://anything.site.com'
Get-UrlType $u
Выдаст:
User: user
Code: 12345678
Subdomain: anything
Альтернативное решение задачи, при условии, что site.com во всех трёх случаях постоянно, можно представить через объединение URI с "хирургией" через обобщённый делегат. Правда это уже более функциональный стиль, а здесь, на форуме, повсеместно императивщина.

YuS_2
11-09-2020, 19:01
На вход скрипта приходят URL трёх видов »
$urls = 'https://anything.site.com/',
'https://site.com/user/anything/anything',
'https://anything.site.com/anything-anything-12345678/anything'

$urls|%{
$url = [uri]$_
if ($url.segments.count -gt 1) {
if ($url.segments[1] -match '-\d+($|/)') {
$digits = $url.segments[1].split('-')[-1] -replace '/'
} else {$user = $url.segments[1] -replace '/'}
} else {$subdomen = $url.host.split('.')[0]}
}
$subdomen
$user
$digits
вопрос только в том, каким образом поступают ссылки и строго ли их по три за один проход поступает, и всегда ли они трех типов подряд... в общем, условия не совсем полные...

greg zakharov
11-09-2020, 19:15
YuS_2, см. выше (http://forum.oszone.net/showpost.php?p=2933718&postcount=12)

Fors1k
11-09-2020, 19:29
строго ли их по три за один проход поступает »
На вход скрипта приходит одного из трёх видов »

YuS_2
11-09-2020, 20:43
YuS_2, см. выше »
угу, страница обновилась уже после отправки и потом увидел, что, по сути, тот же принцип... но подумал, пусть останется, как вариант, лишним не будет. :)
У тебя, кстати, скрипт ограничен версией powershell 7.0, что не есть хорошо, имхо...

Fors1k,
это малоинформативное условие, ибо если приходит одна из трех видов, то логично предположить, что следующим ходом приходит ещё одна ссылка из трех видов и т.д.
Но вот последовательность поступления неясна, т.к. по такому условию допустим вариант, что подряд могут поступать ссылки одного типа неоднократно.
Например, так:
'https://site.com/user/anything/anything'
'https://site.com/user/anything/anything'
'https://site.com/user/anything/anything'
'https://site.com/user/anything/anything'
- это не противоречит условию... но это таки важно, ибо обработка ссылок необходима до заполнения трех переменных значением и уже из них формируется новая ссылка... если, конечно, я правильно понял ТС.

Fors1k
11-09-2020, 20:52
Я так понимаю, что ссылки уже готовы для каждого случая, за исключением одного пробела.
Приходит одна ссылка, получаем переменную, открываем в браузере. И так может хоть сто раз прийти одна ссылка, но с разными переменными:
'https://site.com/Fors1k/anything/anything'
'https://site.com/YuS_2/anything/anything'
'https://site.com/greg_zakharov/anything/anything'
Вот такой вариант решения
[Uri[]]$u = (
'https://site.com/user/anything/anything',
'https://anything.site.com/anything-anything-12345678/anything',
'https://anything.site.com/'
)|Get-Random;cls

$IFuser={
$user=$u.Segments[1].Trim("/")
write-host "Ссылка на пользователя: $user"
start "https://XYZ.com/$user/anything/anything"
}
$IFsub ={
$sub =$u.host.split('.')[0]
write-host "Ссылка на субдомен: $sub"
start "https://$sub.XYZ.com/"
}
$IFpost={
$post=$u.Segments[1].split(("/","-"))[-2]
write-host "Ссылка на пост: $post"
start "https://abc.XYZ.com/anything-anything-$post/anything"
}
switch($u.Segments.Count){1{&$ifsub}4{&$ifuser}3{&$ifpost}}

greg zakharov
11-09-2020, 21:09
скрипт ограничен версией powershell 7.0, что не есть хорошо, имхо...
С чего бы? Там, если так незаметно, используется тернарная операция, которая появилась в семерке, а директива #requires -version 7 только это подчёркивает, дабы не возникало вопросов, дескать, не работает и дыр и пыр в оном духе. Ко всему прочему, давайте начистоту. PowerShell в основе которого лежит платформа .NET Framework де-юре может использоваться, но де-факто - труп, а трупов пинать нехорошо. Так что имхай, не имхай, но как раз оглядка на обратную совместимость - большая ошибка (как и основной тормоз в плане мигрирования на pwsh, ибо в последнем куда более полезных фич. Например, использование указателей в динамических методах, что на примере большого объема данных (не говоря о критичности по времени исполнения) просто пиндыр как важно; перечислять все достоинства от использования самой актуальной версии, полагаю, смысла не имеет. Всё вскрывается на практике. А на практике pwsh способен на многое - это серьёзный аргумент нежели "имхо".

Fors1k, вы желаете вооружённого конфликта?
Я так понимаю, что ссылки уже готовы для каждого случая, за исключением одного пробела.
С идеологической точки зрения URL вообще должны кодироваться escape:
[Uri]::EscapeDataString('https://site.com/name lastname/other')
И что это за crapcode со свитчем?

YuS_2
11-09-2020, 21:24
Приходит одна ссылка, получаем переменную, открываем в браузере. »
этого не было в условии...
Было:
Из первого мне нужен только user
Из второго только цифры (они всегда разные)
Из третьего только субдомейн (в данном случае anything)
...
После в каждом конкретном случае мне нужно сформировать URL и открыть в браузере.
»
Так что, тут ссылка открывается в браузере, только после получения трех отдельных единиц данных...

С чего бы? »
Хотя бы из того, что не везде есть возможность его установки... по разным причинам.

Там, если так незаметно, используется тернарная операция, которая появилась в семерке »
объяснение этого вовсе не требовалось, ибо достаточно заметно... :yes:
И с остальным согласен, но увы... без особой необходимости использования того самого тернарного оператора, получаем искусственное ограничение использования скрипта.
Ну а что поделать, если у микрософта не хватило мозгов/желания/внимания, для реализации данного оператора с первых версий powershell? Видимо, исходили из того, что условный оператор его вполне заменяет...

перечислять все достоинства от использования самой актуальной версии, полагаю, смысла не имеет. »
никакого, ибо достаточно очевидно...

greg zakharov
11-09-2020, 21:46
Хотя бы из того, что не везде есть возможность его установки... по разным причинам.
То же можно сказать, например, и про Python. Так что всё относительно.




© OSzone.net 2001-2012