6

ですから、正規表現を理解し始めたばかりで、学習曲線がかなり急であることがわかりました。ただし、stackoverflowは、私の実験の過程で非常に役立ちました。私が書きたい特定の単語マクロがありますが、それを行う方法がわかりません。ドキュメント内で互いに10語程度の単語内にある2つの単語を見つけて、それらの単語をイタリック体にしたいのですが、単語が10語以上離れているか、順序が異なる場合は、マクロでイタリック体にしないでください。それらの言葉。

私は次の正規表現を使用しています。

\bPanama\W+(?:\w+\W+){0,10}?Canal\b

ただし、その間にランダムな単語を含めて、文字列全体を操作することしかできません。また、.Replace関数では、その文字列を別の文字列に置き換えることしかできず、フォーマットスタイルは変更されません。

これ以上の経験を積んだ人は、これをどのように機能させるかについて考えを持っていますか?することさえ可能ですか?


編集:これが私がこれまでに持っているものです。私が抱えている問題は2つあります。まず、一致する正規表現の中から「パナマ」と「運河」という単語だけを選択し、それらの単語だけを(中間の単語ではなく)置き換える方法がわかりません。次に、別の形式と一致する正規表現を置き換える方法がわかりません。テキストの文字列が異なるだけです。おそらく、単語マクロに精通していないためです。

Sub RegText()
Dim re As regExp
Dim para As Paragraph
Dim rng As Range
Set re = New regExp
re.Pattern = "\bPanama\W+(?:\w+\W+){0,10}?Canal\b"
re.IgnoreCase = True
re.Global = True
For Each para In ActiveDocument.Paragraphs
  Set rng = para.Range
  rng.MoveEnd unit:=wdCharacter, Count:=-1
  Text$ = rng.Text + "Modified"
  rng.Text = re.Replace(rng.Text, Text$)
Next para
End Sub

わかりました。以下のTimWilliamsの助けを借りて、次の解決策をまとめました。いくつかの点で少し不器用で、純粋な正規表現ではありませんが、仕事は完了します。誰かがこれをどうやって進めるかについてより良い解決策やアイデアを持っているなら、私はそれを聞くことに魅了されるでしょう。繰り返しになりますが、検索と置換機能を使用して変更を強制する私の野蛮人は少し恥ずかしいほど粗雑ですが、少なくともそれは機能します...

Sub RegText()
Dim re As regExp
Dim para As Paragraph
Dim rng As Range
Dim txt As String
Dim allmatches As MatchCollection, m As match
Set re = New regExp
re.pattern = "\bPanama\W+(?:\w+\W+){0,13}?Canal\b"
re.IgnoreCase = True
re.Global = True
For Each para In ActiveDocument.Paragraphs

  txt = para.Range.Text

  'any match?
  If re.Test(txt) Then
    'get all matches
    Set allmatches = re.Execute(txt)
    'look at each match and hilight corresponding range
    For Each m In allmatches
        Debug.Print m.Value, m.FirstIndex, m.Length
        Set rng = para.Range
        rng.Collapse wdCollapseStart
        rng.MoveStart wdCharacter, m.FirstIndex
        rng.MoveEnd wdCharacter, m.Length
        rng.Font.ColorIndex = wdOrange
    Next m
  End If

Next para

Selection.Find.ClearFormatting
Selection.Find.Font.ColorIndex = wdOrange
Selection.Find.Replacement.ClearFormatting
Selection.Find.Replacement.Font.Italic = True
With Selection.Find
    .Text = "Panama"
    .Replacement.Text = "Panama"
    .Forward = True
    .Wrap = wdFindContinue
    .Format = True
    .MatchCase = False
    .MatchWholeWord = False
    .MatchWildcards = False
    .MatchSoundsLike = False
    .MatchAllWordForms = False
End With
Selection.Find.Execute Replace:=wdReplaceAll
Selection.Find.ClearFormatting
Selection.Find.Font.ColorIndex = wdOrange
Selection.Find.Replacement.ClearFormatting
Selection.Find.Replacement.Font.Italic = True
With Selection.Find
    .Text = "Canal"
    .Replacement.Text = "Canal"
    .Forward = True
    .Wrap = wdFindContinue
    .Format = True
    .MatchCase = False
    .MatchWholeWord = False
    .MatchWildcards = False
    .MatchSoundsLike = False
    .MatchAllWordForms = False
End With
Selection.Find.Execute Replace:=wdReplaceAll

Selection.Find.ClearFormatting
Selection.Find.Font.ColorIndex = wdOrange
Selection.Find.Replacement.ClearFormatting
Selection.Find.Replacement.Font.ColorIndex = wdBlack
With Selection.Find
    .Text = ""
    .Replacement.Text = ""
    .Forward = True
    .Wrap = wdFindContinue
    .Format = True
    .MatchCase = False
    .MatchWholeWord = False
    .MatchWildcards = False
    .MatchSoundsLike = False
    .MatchAllWordForms = False
End With
Selection.Find.Execute Replace:=wdReplaceAll
End Sub
4

2 に答える 2

6

私はまともなWordプログラマーになるにはほど遠いですが、これで始められるかもしれません。

編集:パラメータ化されたバージョンを含むように更新されました。

Sub Tester()

    HighlightIfClose ActiveDocument, "panama", "canal", wdBrightGreen
    HighlightIfClose ActiveDocument, "red", "socks", wdRed

End Sub


Sub HighlightIfClose(doc As Document, word1 As String, _
                     word2 As String, clrIndex As WdColorIndex)
    Dim re As RegExp
    Dim para As Paragraph
    Dim rng As Range
    Dim txt As String
    Dim allmatches As MatchCollection, m As match

    Set re = New RegExp
    re.Pattern = "\b" & word1 & "\W+(?:\w+\W+){0,10}?" _
                 & word2 & "\b"
    re.IgnoreCase = True
    re.Global = True

    For Each para In ActiveDocument.Paragraphs

      txt = para.Range.Text

      'any match?
      If re.Test(txt) Then
        'get all matches
        Set allmatches = re.Execute(txt)
        'look at each match and hilight corresponding range
        For Each m In allmatches
            Debug.Print m.Value, m.FirstIndex, m.Length
            Set rng = para.Range
            rng.Collapse wdCollapseStart
            rng.MoveStart wdCharacter, m.FirstIndex
            rng.MoveEnd wdCharacter, Len(word1)
            rng.HighlightColorIndex = clrIndex
            Set rng = para.Range
            rng.Collapse wdCollapseStart
            rng.MoveStart wdCharacter, m.FirstIndex + (m.Length - Len(word2))
            rng.MoveEnd wdCharacter, Len(word2)
            rng.HighlightColorIndex = clrIndex
        Next m
      End If

    Next para

End Sub
于 2012-07-06T23:11:14.777 に答える
0

一度に2単語ずつ実行した後であれば、これは私にとってはうまくいきました。

foo([a-zA-Z0-9]+? ){0,10}bar

説明: 単語1()を取得fooし、英数字( )、スペース( )、10回()、単語2([a-zA-Z0-9]+?)が続く単語に一致します。{0,10}bar

これには終止符は含まれていません(必要かどうかはわかりませんでした)が、正規表現の.後に追加したい場合は。0-9

したがって、(擬似コード)構文は次のようになります

$matches = preg_match_all(); // Your function to get regex matches in an array

foreach (those matches) {
    replace(KEY_WORD, <i>KEY_WORD</i>);
}

うまくいけば、それが役立ちます。以下のテストでは、一致するものを強調しました。


働いた:

foo this that bar何とか_

Thefoo economic order war bar

動作しませんでした

fooの経済秩序。ウォーバー

世界的なfooの秩序は数世紀前から存在しており、この期間に人々は農業や酒場などの状況を扱うさまざまで複雑な貿易関係を発展させてきました。

于 2012-07-06T05:34:24.630 に答える