使用 PowerShell 從檔案中提取所有大寫的單詞。據我所知,一切正常,直到最后一行代碼。我的 RegEx 有問題還是我的方法全錯了?
#Extract content of Microsoft Word Document to text
$word = New-Object -comobject Word.Application
$word.Visible = $True
$doc = $word.Documents.Open("D:\Deleteme\test.docx")
$sel = $word.Selection
$paras = $doc.Paragraphs
$path = "D:\deleteme\words.txt"
foreach ($para in $paras)
{
$para.Range.Text | Out-File -FilePath $path -Append
}
#Find all capitalized words :( Everything works except this. I want to extract all Capitalized words
$capwords = Get-Content $path | Select-string -pattern "/\b[A-Z] \b/g"
uj5u.com熱心網友回復:
我修改了您的腳本,并且能夠在我的測驗檔案中獲取所有大寫單詞。
$word = New-Object -comobject Word.Application
$word.Visible = $True
$doc = $word.Documents.Open("D:\WordTest\test.docx")
$sel = $word.Selection
$paras = $doc.Paragraphs
$path = "D:\WordTest\words.txt"
foreach ($para in $paras)
{
$para.Range.Text | Out-File -FilePath $path -Append
}
# Get all words in the content
$AllWords = (Get-Content $path)
# Split all words into an array
$WordArray = ($AllWords).split(' ')
# Create array for capitalized words to capture them during ForEach loop
$CapWords = @()
# ForEach loop for each word in the array
foreach($SingleWord in $WordArray){
# Perform a check to see if the word is fully capitalized
$Check = $SingleWord -cmatch '\b[A-Z] \b'
# If check is true, remove special characters and put it into the $CapWords array
if($Check -eq $True){
$SingleWord = $SingleWord -replace '[\W]', ''
$CapWords = $SingleWord
}
}
我把它作為一個大寫單詞的陣列出現,但如果你想讓它成為一個字串,你總是可以把它連接回來:
$CapString = $CapWords -join " "
uj5u.com熱心網友回復:
PowerShell 使用字串來存盤正則運算式,并且沒有用于正則運算式文字(例如
/.../- )的語法,也沒有用于后位置匹配選項(例如g.默認情況下,PowerShell不區分大小寫,并且需要選擇加入區分大小寫(
-CaseSensitive在 的情況下Select-String)。- 沒有它,
[A-Z]實際上[A-Za-z]與大寫和小寫(英文)字母相同,因此匹配。
- 沒有它,
g選項的等價物是Select-String的-AllMatches開關,它會查找每個輸入行上的所有匹配項(默認情況下,它只查找第一個.什么
Select-String輸出不是字串,即不是直接匹配的行,而是帶有每個匹配元資料型別的包裝物件[Microsoft.PowerShell.Commands.MatchInfo]。- 該型別的實體具有
.Matches包含[System.Text.RegularExpressions.Match]實體陣列的.Value屬性,其屬性包含每個匹配的文本(而該.Line屬性包含完整的匹配行)。
- 該型別的實體具有
把它們放在一起:
$capwords = Get-Content -Raw $path |
Select-String -CaseSensitive -AllMatches -Pattern '\b[A-Z] \b' |
ForEach-Object { $_.Matches.Value }
請注意-Rawwith的使用Get-Content,這大大加快了處理速度,因為整個檔案內容被讀取為單個多行字串- 本質上,Select-String然后將整個內容視為單個“行”。這種優化是可能的,因為您對逐行處理不感興趣,只關心正則運算式在所有行中捕獲的內容。
作為旁白:
$_.Matches.Value利用 PowerShell 的成員 enumeration,您可以類似地利用它來避免$paras顯式回圈段落:
# Use member enumeration on collection $paras to get the .Range
# property values of all collection elements and access their .Text
# property value.
$paras.Range.Text | Out-File -FilePath $path
.NET API 替代方案:
在[regex]::Matches().NET方法允許更簡潔-且效果較好-選擇:
$capwords = [regex]::Matches((Get-Content -Raw $path), '\b[A-Z] \b').Value
請注意,與 PowerShell 相比,.NET regex API默認區分大小寫,因此不需要選擇加入。
.Value 再次利用成員列舉從所有回傳的匹配資訊物件中提取匹配文本。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/376427.html
