> For the complete documentation index, see [llms.txt](https://docs.apryse.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.apryse.com/core/search/text-search.md).

# Search for text in a PDF on Server/Desktop

Learn how to search for text in a PDF using regular expressions and apply link annotations on highlighted results. Full code sample included. The Apryse Server SDK streamlines secure document processi

To search for text in a PDF using regular expression and then apply a link annotation on the highlighted result.

{% hint style="info" %}
In this example, we add a link annotation but any other types of annotations can be applied here such as redaction annotations in the case of a search and redact workflow.
{% endhint %}

{% tabs %}
{% tab title="C#" %}
{% code lineNumbers="true" %}

```csharp
PDFDoc doc = new PDFDoc(filename);
Int32 page_num = 0;
String result_str = "", ambient_string = "";
Highlights hlts = new Highlights();
TextSearch txt_search = new TextSearch();
Int32 mode = (Int32)(TextSearch.SearchMode.e_whole_word | TextSearch.SearchMode.e_page_stop | TextSearch.SearchMode.e_highlight);
String pattern = "";

//use regular expression to find credit card number
mode |= (Int32)(TextSearch.SearchMode.e_reg_expression | TextSearch.SearchMode.e_highlight);
txt_search.SetMode(mode);
String pattern = "\\d{4}-\\d{4}-\\d{4}-\\d{4}"; //or "(\\d{4}-){3}\\d{4}"
txt_search.SetPattern(pattern);

//call Begin() method to initialize the text search.
txt_search.Begin( doc, pattern, mode, -1, -1 );
TextSearch.ResultCode code = txt_search.Run(ref page_num, ref result_str, ref ambient_string, hlts );

if ( code == TextSearch.ResultCode.e_found )
{
  //add a link annotation based on the location of the found instance
  hlts.Begin(doc);
  while (hlts.HasNext())
  {
    Page cur_page = doc.GetPage(hlts.GetCurrentPageNumber());
    double[] quads = hlts.GetCurrentQuads();
    int quad_count = quads.Length / 8;
    for (int i = 0; i < quad_count; ++i)
    {
      //assume each quad is an axis-aligned rectangle
      int offset = 8 * i;
      double x1 = Math.Min(Math.Min(Math.Min(quads[offset + 0], quads[offset + 2]), quads[offset + 4]), quads[offset + 6]);
      double x2 = Math.Max(Math.Max(Math.Max(quads[offset + 0], quads[offset + 2]), quads[offset + 4]), quads[offset + 6]);
      double y1 = Math.Min(Math.Min(Math.Min(quads[offset + 1], quads[offset + 3]), quads[offset + 5]), quads[offset + 7]);
      double y2 = Math.Max(Math.Max(Math.Max(quads[offset + 1], quads[offset + 3]), quads[offset + 5]), quads[offset + 7]);

      Annots.Link hyper_link = Annots.Link.Create(doc, new Rect(x1, y1, x2, y2), Action.CreateURI(doc, "http://www.apryse.com"));
      hyper_link.RefreshAppearance();
      cur_page.AnnotPushBack(hyper_link);
    }
    hlts.Next();
  }
}
```

{% endcode %}

[pdftron.PDF.TextSearch](https://sdk.apryse.com/api/PDFTronSDK/dotnet/api/pdftron.PDF.TextSearch.html) [pdftron.PDF.ContentReplacer](https://sdk.apryse.com/api/PDFTronSDK/dotnet/api/pdftron.PDF.ContentReplacer.html)
{% endtab %}

{% tab title="C++" %}
{% code lineNumbers="true" %}

```cpp
PDFDoc doc(filename);
TextSearch txt_search;
TextSearch::Mode mode = TextSearch::e_whole_word | TextSearch::e_page_stop;
UString pattern("");

//use regular expression to find credit card number
mode |= TextSearch::e_reg_expression | TextSearch::e_highlight;
txt_search.SetMode(mode);
pattern = "\\d{4}-\\d{4}-\\d{4}-\\d{4}"; //or "(\\d{4}-){3}\\d{4}"
txt_search.SetPattern(pattern);

//call Begin() method to initialize the text search.
txt_search.Begin( doc, pattern, mode );
SearchResult result = txt_search.Run();

if ( result )
{
  //add a link annotation based on the location of the found instance
  Highlights hlts = result.GetHighlights();
  hlts.Begin(doc);
  while ( hlts.HasNext() )
  {
    Page cur_page= doc.GetPage(hlts.GetCurrentPageNumber());
    const double *quads;
    int quad_count = hlts.GetCurrentQuads(quads);
    for ( int i = 0; i < quad_count; ++i )
    {
      //assume each quad is an axis-aligned rectangle
      const double *q = &quads[8*i];
      double x1 = min(min(min(q[0], q[2]), q[4]), q[6]);
      double x2 = max(max(max(q[0], q[2]), q[4]), q[6]);
      double y1 = min(min(min(q[1], q[3]), q[5]), q[7]);
      double y2 = max(max(max(q[1], q[3]), q[5]), q[7]);
      Annots::Link hyper_link = Annots::Link::Create(doc, Rect(x1, y1, x2, y2), Action::CreateURI(doc, "http://www.apryse.com"));
      cur_page.AnnotPushBack(hyper_link);
    }
    hlts.Next();
  }
}
```

{% endcode %}

[pdftron::PDF::TextSearch](https://sdk.apryse.com/api/PDFTronSDK/cpp/classpdftron_1_1_p_d_f_1_1_text_search.html) [pdftron::PDF::ContentReplaces](https://sdk.apryse.com/api/PDFTronSDK/cpp/classpdftron_1_1_p_d_f_1_1_content_replacer.html)
{% endtab %}

{% tab title="Go" %}
{% code lineNumbers="true" %}

```go
doc := NewPDFDoc(filename)
txtSearch := NewTextSearch()
mode := TextSearchE_whole_word | TextSearchE_page_stop
pattern := ""

mode = mode | TextSearchE_reg_expression | TextSearchE_highlight
txtSearch.SetMode(uint(mode))
pattern := "\\d{4}-\\d{4}-\\d{4}-\\d{4}"     //or "(\\d{4}-){3}\\d{4}"
txtSearch.SetPattern(pattern)

// call Begin() method to initialize the text search.
txtSearch.Begin(doc, pattern, uint(mode))
searchResult := txtSearch.Run()

if searchResult.IsFound(){
  // add a link annotation based on the location of the found instance
  hlts := searchResult.GetHighlights()
  hlts.Begin(doc)
  
  for hlts.HasNext(){
    curPage := doc.GetPage(uint(hlts.GetCurrentPageNumber()))
    quadsInfo := hlts.GetCurrentQuads()
    
    i := 0
    for i < int(quadsInfo.Size()){
      q := quadsInfo.Get(i)
      // assume each quad is an axis-aligned rectangle 
      x1 := Min(Min(Min(q.GetP1().GetX(), q.GetP2().GetX()), q.GetP3().GetX()), q.GetP4().GetX())
      x2 := Max(Max(Max(q.GetP1().GetX(), q.GetP2().GetX()), q.GetP3().GetX()), q.GetP4().GetX())
      y1 := Min(Min(Min(q.GetP1().GetY(), q.GetP2().GetY()), q.GetP3().GetY()), q.GetP4().GetY())
      y2 := Max(Max(Max(q.GetP1().GetY(), q.GetP2().GetY()), q.GetP3().GetY()), q.GetP4().GetY())
      hyperLink := LinkCreate(doc.GetSDFDoc(), NewRect(x1, y1, x2, y2), ActionCreateURI(doc.GetSDFDoc(), "http://www.apryse.com"))
      curPage.AnnotPushBack(hyperLink)
      i = i + 1
    }
    hlts.Next()
  }
}
```

{% endcode %}
{% endtab %}

{% tab title="Java" %}
{% code lineNumbers="true" %}

```java
PDFDoc doc = new PDFDoc(filename);
TextSearch txt_search = new TextSearch();
int mode = TextSearch.e_whole_word | TextSearch.e_page_stop;
String pattern = "";

//use regular expression to find credit card number
mode |= TextSearch.e_reg_expression | TextSearch.e_highlight;
txt_search.setMode(mode);
String new_pattern = "\\d{4}-\\d{4}-\\d{4}-\\d{4}"; //or "(\\d{4}-){3}\\d{4}"
txt_search.setPattern(new_pattern);

//call Begin() method to initialize the text search.
txt_search.begin(doc, pattern, mode, -1, -1);
TextSearchResult result = txt_search.run();

if (result.getCode() == TextSearchResult.e_found) {
  //add a link annotation based on the location of the found instance
  Highlights hlts = result.getHighlights();
  hlts.begin(doc);
  while (hlts.hasNext()) {
    Page cur_page = doc.getPage(hlts.getCurrentPageNumber());
    double[] q = hlts.getCurrentQuads();
    int quad_count = q.length / 8;
    for (int i = 0; i < quad_count; ++i) {
      //assume each quad is an axis-aligned rectangle
      int offset = 8 * i;
      double x1 = Math.min(Math.min(Math.min(q[offset + 0], q[offset + 2]), q[offset + 4]), q[offset + 6]);
      double x2 = Math.max(Math.max(Math.max(q[offset + 0], q[offset + 2]), q[offset + 4]), q[offset + 6]);
      double y1 = Math.min(Math.min(Math.min(q[offset + 1], q[offset + 3]), q[offset + 5]), q[offset + 7]);
      double y2 = Math.max(Math.max(Math.max(q[offset + 1], q[offset + 3]), q[offset + 5]), q[offset + 7]);
      annots.Link hyper_link = annots.Link.create(doc, new Rect(x1, y1, x2, y2), Action.createURI(doc, "http://www.apryse.com"));
      cur_page.annotPushBack(hyper_link);
    }
    hlts.next();
  }
}
```

{% endcode %}

[com.pdftron.pdf.TextSearch](https://sdk.apryse.com/api/PDFTronSDK/java/com/pdftron/pdf/TextSearch.html) [com.pdftron.pdf.ContentReplacer](https://sdk.apryse.com/api/PDFTronSDK/java/com/pdftron/pdf/ContentReplacer.html)
{% endtab %}

{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
async function main() {
  const doc = await PDFNet.PDFDoc.createFromURL(filename);
  const txtSearch = await PDFNet.TextSearch.create();
  let mode = PDFNet.TextSearch.Mode.e_whole_word + PDFNet.TextSearch.Mode.e_page_stop; // Uses both whole word and page stop
  let pattern = '';

  //use regular expression to find credit card number
  mode += PDFNet.TextSearch.Mode.e_reg_expression + PDFNet.TextSearch.Mode.e_highlight;
  txtSearch.setMode(mode);
  pattern = '\\d{4}-\\d{4}-\\d{4}-\\d{4}'; // or "(\\d{4}-){3}\\d{4}"
  txtSearch.setPattern(pattern);

  //call Begin() method to initialize the text search.
  txtSearch.begin(doc, pattern, mode);
  const result = await txtSearch.run();

  if (result.code === PDFNet.TextSearch.ResultCode.e_found) {
    // add a link annotation based on the location of the found instance
    hlts = result.highlights;
    await hlts.begin(doc);
    while (await hlts.hasNext()) {
      const curPage = await doc.getPage(await hlts.getCurrentPageNumber());
      const quadArr = await hlts.getCurrentQuads();
      for (let i = 0; i < quadArr.length; ++i) {
        const currQuad = quadArr[i];
        const x1 = Math.min(Math.min(Math.min(currQuad.p1x, currQuad.p2x), currQuad.p3x), currQuad.p4x);
        const x2 = Math.max(Math.max(Math.max(currQuad.p1x, currQuad.p2x), currQuad.p3x), currQuad.p4x);
        const y1 = Math.min(Math.min(Math.min(currQuad.p1y, currQuad.p2y), currQuad.p3y), currQuad.p4y);
        const y2 = Math.max(Math.max(Math.max(currQuad.p1y, currQuad.p2y), currQuad.p3y), currQuad.p4y);

        const hyperLink = await PDFNet.LinkAnnot.create(doc, await PDFNet.Rect.init(x1, y1, x2, y2));
        await hyperLink.setAction(await PDFNet.Action.createURI(doc, 'http://www.apryse.com'));
        await curPage.annotPushBack(hyperLink);
      }
      hlts.next();
    }
  }
}
PDFNet.runWithCleanup(main);
```

{% endcode %}

[PDFNet.TextSearch](https://sdk.apryse.com/api/pdfnet-node/PDFNet.TextSearch.html) [PDFNet.ContentReplacer](https://sdk.apryse.com/api/pdfnet-node/PDFNet.ContentReplacer.html)
{% endtab %}

{% tab title="Kotlin" %}
{% code lineNumbers="true" %}

```kotlin
val doc = PDFDoc(filename)
val txt_search = TextSearch()
var mode = TextSearch.e_whole_word or TextSearch.e_page_stop
val pattern = ""

//use regular expression to find credit card number
mode = mode or (TextSearch.e_reg_expression or TextSearch.e_highlight)
txt_search.mode = mode
val new_pattern = "\\d{4}-\\d{4}-\\d{4}-\\d{4}" //or "(\\d{4}-){3}\\d{4}"
txt_search.setPattern(new_pattern)

//call Begin() method to initialize the text search.
txt_search.begin(doc, pattern, mode, -1, -1)
val result = txt_search.run()

if (result.code == TextSearchResult.e_found) {
  //add a link annotation based on the location of the found instance
  val hlts = result.highlights
  hlts.begin(doc)
  while (hlts.hasNext()) {
    val cur_page = doc.getPage(hlts.currentPageNumber)
    val q = hlts.currentQuads
    val quad_count = q.size / 8
    for (i in 0 until quad_count) {
      //assume each quad is an axis-aligned rectangle
      val offset = 8 * i
      val x1 = Math.min(Math.min(Math.min(q[offset + 0], q[offset + 2]), q[offset + 4]), q[offset + 6])
      val x2 = Math.max(Math.max(Math.max(q[offset + 0], q[offset + 2]), q[offset + 4]), q[offset + 6])
      val y1 = Math.min(Math.min(Math.min(q[offset + 1], q[offset + 3]), q[offset + 5]), q[offset + 7])
      val y2 = Math.max(Math.max(Math.max(q[offset + 1], q[offset + 3]), q[offset + 5]), q[offset + 7])
      val hyper_link = com.pdftron.pdf.annots.Link.create(doc, Rect(x1, y1, x2, y2), Action.createURI(doc, "http://www.apryse.com"))
      cur_page.annotPushBack(hyper_link)
    }
    hlts.next()
  }
}
```

{% endcode %}
{% endtab %}

{% tab title="Obj-C" %}
{% code lineNumbers="true" %}

```objc
PTPDFDoc *doc = [[PTPDFDoc alloc] initWithFilepath: filename];
PTTextSearch *txt_search = [[PTTextSearch alloc] init];
unsigned int mode = e_ptwhole_word | e_ptpage_stop;
NSString *pattern = @"";

//use regular expression to find credit card number
mode |= e_ptreg_expression | e_pthighlight;
[txt_search SetMode: mode];
pattern = @"\\d{4}-\\d{4}-\\d{4}-\\d{4}"; //or "(\\d{4}-){3}\\d{4}"
[txt_search SetPattern: pattern];

//call Begin() method to initialize the text search.
[txt_search Begin: doc pattern: pattern mode: mode start_page: -1 end_page: -1];
PTSearchResult *result = [txt_search Run];

if ( result ) 
{
  //add a link annotation based on the location of the found instance
  PTHighlights *hlts = [result GetHighlights];
  [hlts Begin: doc];
  while ( [hlts HasNext] )
  {
    PTPage *cur_page = [doc GetPage: [hlts GetCurrentPageNumber]];
    PTVectorQuadPoint *quads = [hlts GetCurrentQuads];
    int i = 0;
    for ( ; i < [quads size]; ++i )
    {
      //assume each quad is an axis-aligned rectangle
      PTQuadPoint *q = [quads get: i];
      double x1 = MIN(MIN(MIN([[q getP1] getX], [[q getP2] getX]), [[q getP3] getX]), [[q getP4] getX]);
      double x2 = MAX(MAX(MAX([[q getP1] getX], [[q getP2] getX]), [[q getP3] getX]), [[q getP4] getX]);
      double y1 = MIN(MIN(MIN([[q getP1] getY], [[q getP2] getY]), [[q getP3] getY]), [[q getP4] getY]);
      double y2 = MAX(MAX(MAX([[q getP1] getY], [[q getP2] getY]), [[q getP3] getY]), [[q getP4] getY]);
      PTPDFRect * rect = [[PTPDFRect alloc] initWithX1: x1 y1: y1 x2: x2 y2: y2];
      PTAction *action = [PTAction CreateURI: [doc GetSDFDoc] uri: @"http://www.apryse.com"];

      PTLink *hyper_link = [PTLink CreateWithAction: [doc GetSDFDoc] pos: rect action: action];
      [cur_page AnnotPushBack: hyper_link];
    }
    [hlts Next];
  }
}
```

{% endcode %}
{% endtab %}

{% tab title="Swift" %}
{% code lineNumbers="true" %}

```swift
let doc: PTPDFDoc! = PTPDFDoc(filepath: filename)
let txt_search: PTTextSearch! = PTTextSearch()
var mode = e_ptwhole_word.rawValue | e_ptpage_stop.rawValue
var pattern = ""

//use regular expression to find credit card number
mode |= e_ptreg_expression.rawValue | e_pthighlight.rawValue
txt_search.setMode(mode)
pattern = "\\d{4}-\\d{4}-\\d{4}-\\d{4}" //or "(\\d{4}-){3}\\d{4}"
txt_search.setPattern(pattern)

//call Begin() method to initialize the text search.
txt_search.begin(doc, pattern: pattern, mode: mode, start_page: -1, end_page: -1)
let result: PTSearchResult! = txt_search.run()

if (result != nil) {
  //add a link annotation based on the location of the found instance
  let hlts: PTHighlights = result.getHighlights()
  hlts.begin(doc)
  while hlts.hasNext() {
    let cur_page: PTPage = doc.getPage(UInt32(hlts.getCurrentPageNumber()))
    let quads: PTVectorQuadPoint = hlts.getCurrentQuads()
    var i: Int = 0
    
    while i < quads.size() {
      //assume each quad is an axis-aligned rectangle
      let q: PTQuadPoint = quads.get(Int32(i))
      let x1: Double = min(min(min(q.getP1().getX(), q.getP2().getX()), q.getP3().getX()), q.getP4().getX())
      let x2: Double = max(max(max(q.getP1().getX(), q.getP2().getX()), q.getP3().getX()), q.getP4().getX())
      let y1: Double = min(min(min(q.getP1().getY(), q.getP2().getY()), q.getP3().getY()), q.getP4().getY())
      let y2: Double = max(max(max(q.getP1().getY(), q.getP2().getY()), q.getP3().getY()), q.getP4().getY())
      let rect = PTPDFRect(x1: x1, y1: y1, x2: x2, y2: y2)
      let action = PTAction.createURI(doc.getSDFDoc(), uri: "http://www.apryse.com")
      let hyper_link = PTLink.create(withAction: doc.getSDFDoc(), pos: rect, action: action)
      cur_page.annotPushBack(hyper_link)
      i += 1
    }
    hlts.next()
}
```

{% endcode %}
{% endtab %}

{% tab title="PHP" %}
{% code lineNumbers="true" %}

```php
$doc = new PDFDoc($filename);
$txt_search = new TextSearch();
$mode = TextSearch::e_whole_word | TextSearch::e_page_stop;
$pattern = "";

//use regular expression to find credit card number
$mode |= TextSearch::e_reg_expression | TextSearch::e_highlight;
$txt_search->SetMode($mode);
$pattern = "\\d{4}-\\d{4}-\\d{4}-\\d{4}"; //or "(\\d{4}-){3}\\d{4}"
$txt_search->SetPattern($pattern);

//call Begin() method to initialize the text search.
$txt_search->Begin( $doc, $pattern, $mode );
$searchResult = $txt_search->Run();

if ( $searchResult->IsFound() )
{
  //add a link annotation based on the location of the found instance
  $hlts = $searchResult->GetHighlights();
  $hlts->Begin($doc);
  while ( $hlts->HasNext() )
  {
    $cur_page= $doc->GetPage($hlts->GetCurrentPageNumber());
    $quadsInfo = $hlts->GetCurrentQuads();

    for ( $i = 0; $i < $quadsInfo->size(); ++$i )
    {
      //assume each quad is an axis-aligned rectangle
      $q = $quadsInfo->get($i);
      $x1 = min(min(min($q->p1->x, $q->p2->x), $q->p3->x), $q->p4->x);
      $x2 = max(max(max($q->p1->x, $q->p2->x), $q->p3->x), $q->p4->x);
      $y1 = min(min(min($q->p1->y, $q->p2->y), $q->p3->y), $q->p4->y);
      $y2 = max(max(max($q->p1->y, $q->p2->y), $q->p3->y), $q->p4->y);
      $hyper_link = Link::Create($doc->GetSDFDoc(), new Rect($x1, $y1, $x2, $y2), Action::CreateURI($doc->GetSDFDoc(), "http://www.apryse.com"));
      $cur_page->AnnotPushBack($hyper_link);
    }
    $hlts->Next();
  }
}
```

{% endcode %}
{% endtab %}

{% tab title="Python" %}
{% code lineNumbers="true" %}

```python
doc = PDFDoc(filename)
txt_search = TextSearch()
mode = TextSearch.e_whole_word | TextSearch.e_page_stop
pattern = ""

# use regular expression to find credit card number
mode |= TextSearch.e_reg_expression | TextSearch.e_highlight
txt_search.SetMode(mode)
pattern = "\\d{4}-\\d{4}-\\d{4}-\\d{4}"     #or "(\\d{4}-){3}\\d{4}"
txt_search.SetPattern(pattern)

# call Begin() method to initialize the text search.
txt_search.Begin(doc, pattern, mode)
searchResult = txt_search.Run()

if searchResult.IsFound():
  # add a link annotation based on the location of the found instance
  hlts = searchResult.GetHighlights()
  hlts.Begin(doc)
  
  while (hlts.HasNext()):
    cur_page = doc.GetPage(hlts.GetCurrentPageNumber())
    quadsInfo = hlts.GetCurrentQuads()
    
    i = 0
    while i < len(quadsInfo):
      q = quadsInfo[i]
      # assume each quad is an axis-aligned rectangle                        
      x1 = min(min(min(q.p1.x, q.p2.x), q.p3.x), q.p4.x)
      x2 = max(max(max(q.p1.x, q.p2.x), q.p3.x), q.p4.x)
      y1 = min(min(min(q.p1.y, q.p2.y), q.p3.y), q.p4.y)
      y2 = max(max(max(q.p1.y, q.p2.y), q.p3.y), q.p4.y)
      hyper_link = Link.Create(doc.GetSDFDoc(), Rect(x1, y1, x2, y2), Action.CreateURI(doc.GetSDFDoc(), "http://www.apryse.com"))
      cur_page.AnnotPushBack(hyper_link)
      i = i + 1                    
    hlts.Next()
```

{% endcode %}
{% endtab %}

{% tab title="Ruby" %}
{% code lineNumbers="true" %}

```ruby
doc = PDFDoc.new(filename)
txt_search = TextSearch.new
mode = TextSearch::E_whole_word | TextSearch::E_page_stop
pattern = ""

# use regular expression to find credit card number
mode |= TextSearch::E_reg_expression | TextSearch::E_highlight
txt_search.SetMode(mode)
pattern = "\\d{4}-\\d{4}-\\d{4}-\\d{4}"	 #or "(\\d{4}-){3}\\d{4}"
txt_search.SetPattern(pattern)

# call Begin method to initialize the text search.
txt_search.Begin(doc, pattern, mode)
searchResult = txt_search.Run

if searchResult.IsFound
  # add a link annotation based on the location of the found instance
  hlts = searchResult.GetHighlights
  hlts.Begin(doc)
  
  while hlts.HasNext do
    cur_page = doc.GetPage(hlts.GetCurrentPageNumber)
    quadsInfo = hlts.GetCurrentQuads

    i = 0
    while i < quadsInfo.size do
      q = quadsInfo[i]
      # assume each quad is an axis-aligned rectangle						
      x1 = [q.p1.x, q.p2.x, q.p3.x, q.p4.x].min
      x2 = [q.p1.x, q.p2.x, q.p3.x, q.p4.x].max
      y1 = [q.p1.y, q.p2.y, q.p3.y, q.p4.y].min
      y2 = [q.p1.y, q.p2.y, q.p3.y, q.p4.y].max
      hyper_link = Link.Create(doc.GetSDFDoc, Rect.new(x1, y1, x2, y2), Action.CreateURI(doc.GetSDFDoc, "http://www.apryse.com"))
      cur_page.AnnotPushBack(hyper_link)
      i = i + 1
    end			
    hlts.Next
  end
end
```

{% endcode %}
{% endtab %}

{% tab title="VB" %}
{% code lineNumbers="true" %}

```vb
Dim doc As PDFDoc = New PDFDoc(filename)
Dim page_num As Int32 = 0
Dim result_str As String = "", ambient_string As String = ""
Dim hlts As Highlights = New Highlights()
Dim txt_search As TextSearch = New TextSearch()
Dim mode As Int32 = CInt((TextSearch.SearchMode.e_whole_word Or TextSearch.SearchMode.e_page_stop Or TextSearch.SearchMode.e_highlight))
Dim pattern As String = ""

' use regular expression to find credit card number
mode = mode Or CInt((TextSearch.SearchMode.e_reg_expression Or TextSearch.SearchMode.e_highlight))
txt_search.SetMode(mode)
pattern = "\d{4}-\d{4}-\d{4}-\d{4}"
txt_search.SetPattern(pattern)

' call Begin method to initialize the text search.
txt_search.Begin(doc, pattern, mode, -1, -1)
Dim code As TextSearch.ResultCode = txt_search.Run(page_num, result_str, ambient_string, hlts)

If code = TextSearch.ResultCode.e_found Then
  ' add a link annotation based on the location of the found instance
  hlts.Begin(doc)
  While hlts.HasNext()
    Dim cur_page As Page = doc.GetPage(hlts.GetCurrentPageNumber())
    Dim quads As Double() = hlts.GetCurrentQuads()
    Dim quad_count As Integer = quads.Length / 8

    For i As Integer = 0 To quad_count - 1
      Dim offset As Integer = 8 * i
      Dim x1 As Double = Math.Min(Math.Min(Math.Min(quads(offset + 0), quads(offset + 2)), quads(offset + 4)), quads(offset + 6))
      Dim x2 As Double = Math.Max(Math.Max(Math.Max(quads(offset + 0), quads(offset + 2)), quads(offset + 4)), quads(offset + 6))
      Dim y1 As Double = Math.Min(Math.Min(Math.Min(quads(offset + 1), quads(offset + 3)), quads(offset + 5)), quads(offset + 7))
      Dim y2 As Double = Math.Max(Math.Max(Math.Max(quads(offset + 1), quads(offset + 3)), quads(offset + 5)), quads(offset + 7))
      Dim hyper_link As pdftron.PDF.Annots.Link = pdftron.PDF.Annots.Link.Create(doc, New Rect(x1, y1, x2, y2), pdftron.PDF.Action.CreateURI(doc, "http://www.apryse.com"))
      hyper_link.RefreshAppearance()
      cur_page.AnnotPushBack(hyper_link)
    Next

    hlts.Next()
  End While
End If
```

{% endcode %}
{% endtab %}
{% endtabs %}

[Search PDF files for text](/core/get-started/samples/textsearchtest.md) - Full Sample Full code sample which shows how to use TextSearch to search text on PDF pages using regular expressions.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.apryse.com/core/search/text-search.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
