Показать полную графическую версию : Select-String. Парсинг нескольких значений между наборами символов.
Всем привет!
Уже второй день бьюсь с задачей: есть текстовый файл, из которого необходимо вывести на экран несколько слов/цифр, находящихся между определённым текстом.
...
!--PREVINFO_START-->Autodesk AutoCAD Electrical 2015<!--PREVINFO_END--></dfsdferwer
'word-break:break-all'>УH5S SV65 V9У1 WDL3 </td></tr>erwedfsdf
td align=left id=2>21T81</td><td align=leftwerewrwer
...
!--PREVINFO_START-->Autodesk AutoCAD 2018<!--PREVINFO_END--></dfsdferwer
'word-break:break-all'>YWP8 10NT JHGJ NJJZ </td></tr>erwedfsdf
td align=left id=2>T2281</td><td align=leftwerewrwer
Такого рода записей может быть несколько из-за нескольких установленных версий Автокада.
Autodesk AutoCAD Electrical 2015
УH5S SV65 V9У1 WDL3
21T81
Autodesk AutoCAD 2018
YWP8 10NT JHGJ NJJZ
T2281
Первую строку достаю командой:
(Select-String "(?<=!--PREVINFO_START-->)(.*?)(?=]<!--PREVINFO_END--></)" -InputObject $content -AllMatches | foreach {$_.matches}).value
Но при этом парсится сразу две первые строчки названий программы. Но не могу понять, как задать сразу несколько условий в запросе выше, чтобы парсилось и название, и серийник, и код продукта. Можете подтолкнуть в правильном направлении?
param(
$path = "C:\files\qwe.txt"
)cls
(gc $path|sls '(?<=>).+?(?=<)' -all).Matches.Value
param(
$path = "C:\files\qwe.txt"
)cls
(gc $path|sls '(?<=>).+?(?=<)' -all).Matches.Value »
Извините, я привёл только кусок текста. В полном варианте много где встречается набор символов, начинающихся с ">" и заканчивающихся на "<". В итоге в выводе получается много лишней информации.
<!--PREVINFO_START-->Autodesk AutoCAD Electrical 2015
</td>
<td align=left id=1>&nbsp;
<td align=left id=2>&nbsp;
<td align=left id=1 width=15%>Серийный номер:
<td align=left id=2>
<!--PREVINFO_START-->421-64324142
</td>
<td align=left id=1 width=15%>Ключ продукта:
<td align=left id=2>21T81
<td align=left id=1>&nbsp;
<td align=left id=2>&nbsp;
<td align=left id=1 width=15%>Код запроса:
Скажите, можно ли в той конструкции, которую вы написали, использовать несколько условий, т.е. обычными словами:
Найти все вхождения в файле, располагающиеся между набором символов ("!--PREVINFO_START-->" и "]<!--PREVINFO_END--></") ИЛИ ("'word-break:break-all'>" и "</td></tr>erwedfsdf") ИЛИ ("td align=left id=2>" и "</td><td align=leftwerewrwer") ?
DJ Mogarych
18-07-2020, 11:43
(gc C:\temp\test\text.txt) -replace "^.*?gt;" -replace "<.*?$"
Регулярное выражение на всю группу строк с подмасками. Выводим подмаски.
$regexp = "!--PREVINFO_START-->(.*?)<!--PREVINFO_END--></dfsdferwer
'word-break:break-all'>(.*?)</td></tr>erwedfsdf
td align=left id=2>(.*?)</td>"
Select-String $regexp -InputObject $content -AllMatches |
% {$_.Matches | % {$_.Groups[1..3].Captures.Value; "`n"}}
Скажите, можно ли в той конструкции, которую вы написали, использовать несколько условий »
param(
$path = "C:\files\qwe.txt"
)cls
$name = "(?<=PREVINFO_START-->).*(?=<!--PREVINFO_END)"
$serial = "(?<=word-break:break-all'>).*(?=</td>)"
$code = "(?<=align\=left id\=2>).*(?=</td)"
(gc $path|sls "$name|$serial|$code" -all).Matches.Value
Уже второй день бьюсь с задачей »
Задача разовая или периодическая, которая требует автоматизации? Лучше от этого отталкиваться...
Можете подтолкнуть в правильном направлении? »
Если говорить о правильном направлении, то лучше декодировать текст, чтобы получить валидный html текст и его уже парсить на предмет необходимых тегов таблицы.
gc test.txt -enc utf8|%{[net.webutility]::htmldecode($_)}
и далее, либо воспользоваться встроенным парсером html, либо (что лучше и будет работать, в том числе и в версиях powershell core) воспользоваться внешним модулем PowerHTML
#---Эту секцию можно удалить после однократного запуска скрипта от имени админа ------------------
# Установка дополнительного модуля PowerHTML, для независимого парсинга HTML
# Может потребоваться ручное подтверждение установки.
if (!(get-module -list powerhtml)) {
write-verbose "Installing PowerHTML module for the current user..."
install-module powerhtml #-scope currentuser
}
#-----------------------------------------------------------------------------------------
ivan.vas
15-10-2021, 15:11
(gc $path|sls "$name|$serial|$code" -all).Matches.Value »
Подскажите, при такой конструкции получается вывод следующий будет?
$name
$serial
$code
Есть ли возможность вывода в одну строку, к примеру вот так:
$name $serial $code
$name $serial $code
$name $serial $code
$name $serial $code
$name $serial $code
$name $serial $code
чтобы так выводить надо преобразовывать под определенный формат, для примера чтобы было понятно что я имею ввиду:
$hash = [Ordered]@{
'name' = 'a', 'b', 'c'
'serial' = 1, 2, 3
'code' = 'i', 'j', 'k'
}
foreach ($i in $hash.GetEnumerator()) {
'{0,-6}: {1}' -f $i.Name, "$($i.Value)"
}
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.
Available in ZeroNet 1osznRoVratMCN3bFoFpR2pSV5c9z6sTC