使用PowerShell从文档中提取所有大写单词



使用PowerShell从文档中提取所有大写单词。据我所知,直到最后一行代码,一切都能正常工作。我的RegEx出了问题,还是我的方法都错了?

#Extract content of Microsoft Word Document to text
$word = New-Object -comobject Word.Application
$word.Visible = $True 
$doc = $word.Documents.Open("D:Deletemetest.docx") 
$sel = $word.Selection
$paras = $doc.Paragraphs
$path = "D:deletemewords.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" 
  • PowerShell使用字符串来存储正则表达式,并且对于正则表达式文本(如/.../(和位置后匹配选项,如g,都没有语法。

  • PowerShell默认情况下不区分大小写,并要求选择加入以区分大小写(在Select-String的情况下为-CaseSensitive(。

    • 如果没有这一点,[A-Z]实际上与[A-Za-z]相同,因此匹配大写和小写(英文(字母
  • 等效于g选项的是Select-String-AllMatches开关,它在每个输入行上查找所有匹配项(默认情况下,它只查找first

  • Select-String输出的不是字符串,即不是直接匹配的行,而是具有关于每个匹配的元数据的[Microsoft.PowerShell.Commands.MatchInfo]类型的包装器对象

    • 该类型的实例具有包含[System.Text.RegularExpressions.Match]实例数组的.Matches属性,其.Value属性包含每个匹配的文本(而.Line属性包含完整的匹配行(

把所有这些放在一起:

$capwords = Get-Content -Raw $path |
Select-String -CaseSensitive -AllMatches -Pattern 'b[A-Z]+b' |
ForEach-Object { $_.Matches.Value }

注意-RawGet-Content的使用,这大大加快了处理速度,因为整个文件内容被读取为单个多行字符串-本质上,Select-String然后将整个内容视为单个"em";行";。这种优化是可能的,因为您对逐行处理不感兴趣,只关心regex在所有行中捕获的内容。

题外话:

$_.Matches.Value利用了PowerShell的成员访问枚举,您可以类似地利用它来避免必须显式地循环$paras中的段落:

# Use member-access 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默认情况下区分大小写,因此不需要选择加入。

CCD_ 22再次利用成员访问枚举来从所有返回的匹配信息对象中提取匹配文本。

我修改了您的脚本,并能够在测试文档中获得所有大写单词。

$word = New-Object -comobject Word.Application
$word.Visible = $True 
$doc = $word.Documents.Open("D:WordTesttest.docx") 
$sel = $word.Selection
$paras = $doc.Paragraphs
$path = "D:WordTestwords.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 " "

最新更新