C#: Searching a text in Word and getting the range of the result
I can find a text in a Word file via:
Word.Range range = wordApp.ActiveDocument.Content;
Word.Find fin开发者_JS百科d = range.Find;
find.Text = "xxx";
find.ClearFormatting();
find.Execute(ref missing, ref missing, ref missing, ref missing, ref missing,
ref missing, ref missing, ref missing, ref missing, ref missing,
ref missing, ref missing, ref missing, ref missing, ref missing);
This tells me if the text is found. But I need the range of the found text-piece.
Have you tried this:
range.Find.Execute(
ref missing, ref missing, ref missing, ref missing, ref missing,
ref missing, ref missing, ref missing, ref missing, ref missing,
ref missing, ref missing, ref missing, ref missing, ref missing);
while (range.Find.Found)
{
//Get selected index.
// Do as you please with range...
//Positions: range.Start... range.End
//search again
range.Find.Execute(
ref missing, ref missing, ref missing, ref missing, ref missing,
ref missing, ref missing, ref missing, ref missing, ref missing,
ref missing, ref missing, ref missing, ref missing, ref missing);
}
The range object should be changed by executing find on it.
So, likely you'd use range.Start
and range.End
to get the character positions.
Reference
Gets a range from word using find method and format it.
//Parameter contains what you want to find.
_wordApp.Selection.Find.Execute(title);
Word.Range range = _wordApp.Selection.Range;
if (range.Text.Contains(title))
{
//gets desired range here it gets last character to make superscript in range
Word.Range temprange = _document.Range(range.End - 1, range.End);
temprange.Select();
Word.Selection currentSelection = _wordApp.Selection;
currentSelection.Font.Superscript = 1;
}
range.Find.Execute
returns true
if found, and sets range
to the found range:
var range = doc.Range();
while ( range.Find.Execute("xxx") )
Debug.Print( range.Text );
Note that range.Find.Execute
will search the range after range
if range
is already a match for the Find conditions (after the first range.Find.Execute
).
For example, this VBA Macro will find only the second "b" :
Sub Macro1()
ActiveDocument.Range.Text = "abba"
Dim r As Range
Set r = ActiveDocument.Range(1, 2) ' the first "b"
Debug.Print r.Start; r.End ' prints " 1 2 "
Debug.Print r.Find.Execute("b") ' prints "True"
Debug.Print r.Start; r.End ' prints " 2 3 "
Debug.Print r.Find.Execute("b") ' prints "False" (if r.Find.Wrap = wdFindStop)
Debug.Print r.Start; r.End ' prints " 2 3 "
End Sub
Can be solved like this:
/// <summary>
/// Find all
/// </summary>
/// <param name="range"></param>
/// <param name="findText">Find content</param>
public static List<Range> FindAll(this Range range, string findText)
{
int start = range.Start;
int end = range.End;
List<Range> ranges = new List<Range>();
range.Find.Execute(FindText: findText, MatchCase: true);
while (range.Find.Found)
{
//The search will change the range, here is an out-of-range judgment
if (range.Start > end)
break;
ranges.Add(range.Document.Range(range.Start, range.End));
range.Find.Execute(FindText: findText, MatchCase: true);
}
//Restore the original range
range.SetRange(start, end);
return ranges;
}
You can also create an extension method:
/// <summary>
/// 查找第一个
/// </summary>
/// <param name="range"></param>
/// <param name="findText">查找内容</param>
/// <returns>没有找到为空</returns>
public static Range FindFirst(this Range range, string findText)
{
int start = range.Start;
int end = range.End;
bool isOk = range.Find.Execute(FindText: findText, MatchCase: true);
if (isOk)
{
var newRange = range.Document.Range(range.Start, range.End);
range.SetRange(start, end);
return newRange;
}
else
return null;
}
精彩评论