#regex #powershell
#регулярное выражение #powershell
Вопрос:
Я могу найти первое совпадение в каждом документе, который я ищу, но не могу перечислить все совпадения, найденные в каждом документе, когда совпадений несколько. Я пробовал несколько способов перебора хэш-таблицы совпадений, но, похоже, не могу понять это правильно. Есть ли способ сделать это?
$RX = "(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(?:.|dot|[dot]|[.])){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)"
$WordFiles = Get-ChildItem $Directory -include *.doc, *.docx -recurse
$Directory = "c:temp"
$objWord = New-Object -Com Word.Application
foreach ($fileSearched in $WordFiles) {
$objWord.Visible = $false
$objWord.DisplayAlerts = "wdAlertsNone"
$objDocument = $objWord.Documents.Open("$fileSearched")
if ($objdocument.Content.Text -match $RX){
Foreach ($found in $_.Matches) { #| ForEach-Object {$_.Value}
$file2.WriteLine("{0},{1}",$matches[$_], $filesearched.fullname)
write-host $_.matches
write-host $_.value
write-host $found
}
}
$file2.close()
}
$objWord.Quit()
Ответ №1:
-match
Версия регулярных выражений Powershell вернет только первое совпадение, и, насколько я знаю, нет способа заставить его находить глобальные совпадения.
Однако вы можете переключиться на использование функции [regex]
класса matches
, которая соответствует глобально по умолчанию.
([regex]::matches($objdocument.Content.Text, $RX))
Обновить
Я полагаю, вам также нужно будет переключиться $_.Matches
на $_.Value
примеры per здесь.
Комментарии:
1. Я попробовал это и получил сообщение об ошибке: «Неожиданный токен’: совпадения’ в выражении или операторе».
2. @user2506096 — Обновлено, можете ли вы попробовать с
::
.3. Похоже, это сработало, спасибо! Теперь мне просто нужно выяснить, как правильно перебирать найденные совпадения.
4. Если подумать, кажется, что он входит в блок if, даже если в некоторых документах не должно быть совпадений.
5. Если вы можете синтезировать простой пример выполнения образца текста, который не дает желаемого результата, я мог бы помочь.
Ответ №2:
Я просмотрел ссылку, предоставленную cchamberlain, и придумал:
$CSV = "c:tempoutput.csv"
$RX = "(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(?:.|dot|[dot]|[.])){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)"
$WordFiles = Get-ChildItem $Directory -include *.doc, *.docx -recurse
$Directory = "c:temp"
$objWord = New-Object -Com Word.Application
$file2 = new-object System.IO.StreamWriter($CSV,$true) #Append or Create a new file Stream.
$file2.WriteLine('Matches,File_Path') # write header
foreach ($fileSearched in $WordFiles) {
$objWord.Visible = $false
$objWord.DisplayAlerts = "wdAlertsNone"
$objDocument = $objWord.Documents.Open("$fileSearched")
$words = ([regex]::matches($objdocument.Content.Text,$RX) | %{$_.value})
foreach ($word in $words){
$file2.WriteLine("{0},{1}",$word, $filesearched.fullname)
}
$file2.close()
$objWord.Quit()