Powershell: вытащить URL из строки
Я вытаскиваю строку из текстового файла, который выглядит следующим образом:
C:\Users\users\Documents\Firefox\tools\Install.ps1:37: Url = "https://somewebsite.com"
Мне нужно кое-как удалить все, кроме URL, чтобы он выглядел так:
https://www.somewebsite.com
Вот что я попробовал:
$Urlselect = Select-String -Path "$zipPath\tools\chocolateyInstall.ps1" -Pattern "url","Url"-List # Selects URL download path
$Urlselect = $Urlselect -replace ".*" ","" -replace ""*.","" # remove everything but the download link
но это ничего не значит сделать. Я думаю, что это будет связано с регулярным выражением, но я не уверен, как это выразить. Любая помощь приветствуется. Спасибо
1 ответ
Я предлагаю использовать switch
заявление с -Regex
а также -File
опции:
$url = switch -regex -file "$zipPath\tools\chocolateyInstall.ps1" {
' Url = "(.*?)"' { $Matches[1]; break }
}
-file
маркиswitch
цикл по всем строкам указанного файла.-regex
интерпретирует условные переходы как регулярные выражения, а автоматический$Matches
переменная может быть использована в связанном блоке скрипта ({ ... }
) для доступа к результатам матча, в частности, к какой 1-й (и единственной) группе захвата в регулярном выражении ((...)
) захваченный - URL интереса.break
останавливает обработку, когда найден 1-й матч. (Чтобы продолжить сопоставление, используйтеcontinue
).
Если вы хотите использовать Select-String
:
$url = Select-String -List ' Url = "(.*?)"' "$zipPath\tools\chocolateyInstall.ps1" |
ForEach-Object { $_.Matches.Groups[1].Value }
Обратите внимание, что switch
Решение будет работать намного лучше.
Что касается того, что вы пытались:
Select-String -Path "$zipPath\tools\chocolateyInstall.ps1" -Pattern "url","Url"
Select-String
по умолчанию нечувствителен к регистру, поэтому нет необходимости указывать варианты регистра для одной и той же строки. (И наоборот, вы должны использовать -CaseSensitive
переключиться на принудительное сопоставление с учетом регистра).
Также обратите внимание, что Select-String
не выводит совпадающую строку напрямую, как строку, а как объекты с информацией о совпадении; чтобы получить соответствующую строку, перейдите к .Line
свойство [1].
$Urlselect -replace ".*" ","" -replace ""*.",""
".*" "
а также ""*."
привести к синтаксическим ошибкам, потому что вы забыли выйти из _embedded "
как `"
,
В качестве альтернативы используйте '...'
(литеральные строки в одинарных кавычках), которые позволяют вставлять "
как есть и обычно предпочтительнее для регулярных выражений и операндов-заменителей, потому что нет никакой путаницы в том, какие части PowerShell может интерпретировать заранее (расширение строки).
Тем не менее, даже если проблема с побегом решена, ваша -replace
операции не работали бы, потому что .*"
соответствует жадно и, следовательно, до последнего "
; Вот исправленное решение с не жадным сопоставлением и опущенным операндом замены (что делает его по умолчанию пустой строкой):
PS> 'C:\...ps1:37: Url = "https://somewebsite.com"' -replace '^.*?"' -replace '"$'
https://somewebsite.com
^.*?"
не жадно заменяет все до первого"
,"$
заменяет"
в конце строки.
Тем не менее, вы можете сделать это с помощью одного -replace
операция, используя то же регулярное выражение, что и с switch
Решение наверху:
PS> 'C:\...ps1:37: Url = "https://somewebsite.com"' -replace '^.*?"(.*?)"', '$1'
https://somewebsite.com
$1
в замене операнд относится к 1-й группе захвата ((...)
) захваченный, то есть голый URL; для получения дополнительной информации см. этот ответ.
[1] Обратите внимание, что есть зеленое предложение, которое еще не реализовано в Windows PowerShell Core 6.2.0, чтобы Select-String
излучать струны напрямую, используя предложенную -Raw
Переключатель - см. https://github.com/PowerShell/PowerShell/issues/7713