【问题标题】:Regex not working for finding within range in word document正则表达式不适用于在 word 文档中查找范围内
【发布时间】:2019-01-25 05:33:02
【问题描述】:

正则表达式不工作,要提取两个部分之间的内容(函数工作正常,但可能我没有提到正确的正则表达式来查找)

ExtractFromWordDoc"D:\Scan.doc" '(?:\d{2}\.\d).*(?:Non-Payment)'  '(?:\d{2}\.\d).*(?:Financial covenants and other obligation)'

Word文档内容(需要提取29.1和29.2之间的信息)

29.1 不付款

债务人不会在到期日支付任何根据财务文件在其表示应付的地点和货币支付的应付金额,除非:

(a) 其未能付款的原因是: (i) 行政或技术错误;要么 (b) [在以下期限内付款: (i)(在上述 (a)(i) 段的情况下),到期日的 [ ] 个工作日;

29.2 财务契约和其他义务

(a) 第 27 条(财务契约)的任何要求未得到满足[或债务人不遵守第 26 条(信息承诺)][和/或第 28 条(一般承诺)的规定]。

function ExtractFromWordDoc{
Param([string]$SourceFile, [string]$SearchKeyword1, [string]$SearchKeyword2)

$word = New-Object -ComObject Word.Application
$word.Visible = $false
$doc = $word.Documents.Open($SourceFile,$false,$true)
$sel = $word.Selection 
$paras = $doc.Paragraphs 
foreach ($para in $paras) 
{ 
    if ($para.Range.Text -match $SearchKeyword1)
    {
        $startPosition = $para.Range.Start
       }
    if ($para.Range.Text -match $SearchKeyword2)
    {
        $endPosition = $para.Range.Start
        break
    }
} 

[array]$content=New-Object System.Collections.ArrayList
$doc.Range($startPosition, $endPosition).Copy()
$content=Get-Clipboard -Raw
$content = $content -replace "'", ""

# cleanup com objects
$doc.Close()
$word.Quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($doc) | Out-Null
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($word) | Out-Null
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()
}

【问题讨论】:

    标签: regex powershell


    【解决方案1】:

    您在正则表达式中只有一个小错误。

    示例文本为Non-payment,但正则表达式匹配Non-Payment(区分大小写)

    如果您将'(?:\d{2}\.\d).*(?:Non-Payment)' 更改为'(?:\d{2}\.\d).*(?:Non-payment)',它应该可以工作。

    另一个注意事项是您在(?:\d{2}\.\d).*(?:Financial covenants and other obligation) 中缺少obligations 中的s,但我不认为这会导致问题。

    免责声明:我没有测试您的代码,只测试了您的正则表达式。

    编辑:

    我测试了以下

    function ExtractFromWordDoc{
    Param([string]$SourceFile, [string]$SearchKeyword1, [string]$SearchKeyword2)
    
    $word = New-Object -ComObject Word.Application
    $word.Visible = $false
    $doc = $word.Documents.Open($SourceFile,$false,$true)
    $sel = $word.Selection 
    $paras = $doc.Paragraphs 
    foreach ($para in $paras) 
    { 
        if ($para.Range.Text -match $SearchKeyword1)
        {
            #"Point 1"
            $startPosition = $para.Range.Start
           }
        if ($para.Range.Text -match $SearchKeyword2)
        {
            #"Point 2"
            $endPosition = $para.Range.Start
            break
        }
    } 
    
    [array]$content=New-Object System.Collections.ArrayList
    $doc.Range($startPosition, $endPosition).Copy()
    $content=Get-Clipboard -Raw
    $content = $content -replace "'", ""
    
    # cleanup com objects
    $doc.Close()
    $word.Quit()
    [System.Runtime.Interopservices.Marshal]::ReleaseComObject($doc) | Out-Null
    [System.Runtime.Interopservices.Marshal]::ReleaseComObject($word) | Out-Null
    [System.GC]::Collect()
    [System.GC]::WaitForPendingFinalizers()
    }
    
    ExtractFromWordDoc "C:\testing\test.doc" '(?:\d{2}\.\d).*(?:Non-payment)'  '(?:\d{2}\.\d).*(?:Financial covenants and other obligation)'
    

    剪贴板中的输出是:

    29.1 Non-payment
    An Obligor does not pay on the due date any amount payable pursuant to a Finance Document at the place at and in the currency in which it is expressed to be payable unless:
    (a) its failure to pay is caused by: (i) administrative or technical error; or (b) [payment is made within: (i) (in the case of paragraph (a)(i) above), [ ] Business Days of its due date; 
    

    如果我在函数末尾添加$content,它会将此文本输出到控制台。

    【讨论】:

    • 试过了,没用...正确获取第一部分行...但是对于第二个关键字,它没有
    • 我对其进行了测试,它工作正常,它匹配正则表达式之间的文本,但不包括 29.2 Financial covenants and other obligations 及以下 - 这是所需的行为吗?
    • 因为我在370页的文档中搜索,它给出不同的结果,因为单词搜索可能存在于其他地方..但它前面的数字不能......所以不知道为什么它不起作用...任何建议
    • 我们是否需要清除剪贴板...因为用于复制的内容
    • 您能否提供导致错误匹配的字符串示例,即匹配的第一行,然后是匹配后立即出现的行?
    【解决方案2】:

    要存储找到的文本,我建议使用StringBuilder 类。

    function ExtractFromWordDoc{
      Param([string]$SourceFile, [string]$SearchKeyword1, [string]$SearchKeyword2)
    
      $word = New-Object -ComObject Word.Application
      $word.Visible = $false
      $doc = $word.Documents.Open($SourceFile, $false, $true)
    
      $sb = New-Object System.Text.StringBuilder
    
      $text = $null
    
      foreach ($para in $doc.Paragraphs)
      {
        if ($para.Range.Text -match $SearchKeyword1)
        {
          while (1)
          {
            [void]$sb.AppendLine($foreach.current.Range.Text)
            if (-not $foreach.MoveNext())
            {
              break # we ran out of paragraphs
            }
            if ($foreach.current.Range.Text -match $SearchKeyword2)
            {
              $text = $sb.ToString() # the searched text was found
              break
            }
          }
          break
        }
      }
    
      $text # let's return something usefull
    
      # cleanup com objects
      $doc.Close()
      $save=$false
      $word.Quit([ref]$save)
      [System.Runtime.Interopservices.Marshal]::ReleaseComObject($doc) | Out-Null
      [System.Runtime.Interopservices.Marshal]::ReleaseComObject($word) | Out-Null
      [System.GC]::Collect()
      [System.GC]::WaitForPendingFinalizers()
    }
    
    ExtractFromWordDoc 'C:\testing\test.doc' '^\s*\d\d\.\d\s+Non-payment' '^\s*\d\d\.\d\s+Financial covenants and other obligation'
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-13
      • 1970-01-01
      • 2023-04-11
      • 2011-04-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多