diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0819aba8..37e50249 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,7 +3,8 @@
 ## Enhancements
 
 - Dlang highlighter: added suport for HEREDOC strings literal of type `q"()"` `q"[]"`, `q"<>"` and `q"{}"`. "Custom" HEREDOC strings literal wont be handled as they might be removed as per DIP 1026.
-- Docking: added disalog to remind that docking is locked in certain scenarios. (#30)
+- Docking: added a dialog to remind that docking is locked in certain scenarios. (#30)
+- Search Replace: the result of _FindAll_ when the string to seach is a regular expression are highlighted. (#14)
 - TODO list: a new option, _disableIfMoreFilesThan_, allows to disable auto refreshing of the list could be slow when the current project is huge.
 
 ## Bugs fixed
diff --git a/docs/widgets_search.md b/docs/widgets_search.md
index 11bfaadb..b3935b0e 100644
--- a/docs/widgets_search.md
+++ b/docs/widgets_search.md
@@ -12,9 +12,9 @@ The _find and replace_ widget allows to find and replace text patterns in the fo
 - **whole word**: Only searches for the whole string.
 - **backward**: Searches from the current position to the top.
 - **from cursor**: When not checked the operation always starts from the top of the document.
-- **case sensitive**: When unchecked the characters case is ignored.
+- **case sensitive**: When unchecked the characters case is ignored. Note that this affects the way regexes are compiled.
 - **prompt**: A confirmation is required to replace a match.
-- **allow regex**: When checked, the search is performed by a regex engine. Note that it doesn't mean that the pattern to find has to be a regex).
+- **allow regex**: When checked, the search is performed by a regex engine.
 
 By default <kbd>CTRL</kbd> + <kbd>F</kbd> is used to pass the current identifier to the first field and <kbd>F3</kbd> to execute a search.
 The _Find all_ results are displayed in the [messages widget](widgets_messages.html), with the context and they can be clicked.
diff --git a/src/u_search.pas b/src/u_search.pas
index 6a74b256..8e834050 100644
--- a/src/u_search.pas
+++ b/src/u_search.pas
@@ -7,9 +7,9 @@ interface
 uses
   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
   Menus, StdCtrls, actnList, Buttons, SynEdit, SynEditSearch, SynEditTypes,
-  u_common, u_mru, u_widget, u_synmemo, u_interfaces, u_observer, strutils,
-  u_writableComponent, u_dialogs, u_sharedres, u_dsgncontrols,
-  SynEditTextBuffer;
+  RegExpr, SynEditTextBuffer, strutils,
+  u_common, u_mru, u_widget, u_synmemo, u_interfaces, u_observer,
+  u_writableComponent, u_dialogs, u_sharedres, u_dsgncontrols;
 
 type
 
@@ -459,7 +459,13 @@ var
   msg: string;
   fmt: string;
   i: integer;
+  j: integer = 0;
+  k: integer;
+  o: integer = -1;
   res: array of TPoint = nil;
+  r: TRegExpr;
+  s: string;
+  rStart: integer;
 begin
   result := 0;
   search := TSynEditSearch.Create;
@@ -496,11 +502,53 @@ begin
       msgs.message(msg, nil, amcMisc, amkInf);
     end;
     fmt := fileName + '(%d,%d): "%s"';
-    for i := 0 to high(res) do
+    // highlighting
+    if ssoRegExpr in options then
     begin
-      msg := format(fmt, [res[i].Y, res[i].X, Trim(lines[res[i].Y-1])]);
+      r := TRegExpr.Create(fToFind);
+      try
+        r.ModifierI := not (ssoMatchCase in options);
+        for i := 0 to high(res) do
+        begin
+          msg := Trim(lines[res[i].Y-1]);
+          // current result is on same line as previous
+          if res[i].Y = o then
+            j += 1
+          else
+            j := 0;
+          rStart := 1;
+          s := '';
+          k := 0;
+          if r.Exec(msg) then
+          repeat
+            s += msg[rStart .. r.MatchPos[0]-1];
+            // count of time we got the same line as result is the nth match to highlight
+            if k = j then
+            begin
+              s += '`' + r.Match[0] + '`';
+              rStart := r.MatchPos[0] + r.MatchLen[0];
+              // dont bother with slicing trailing results once highlighting done
+              break;
+            end
+            else
+              s += r.Match[0];
+            rStart := r.MatchPos[0] + r.MatchLen[0];
+            k += 1;
+          until
+            not r.ExecNext();
+          s += msg[rStart .. msg.length];
+          msgs.message(format(fmt, [res[i].Y, res[i].X, s]), nil, amcMisc, amkInf);
+          o := res[i].Y;
+        end;
+      finally
+        r.Free;
+      end;
+    end
+    else for i := 0 to high(res) do
+    begin
+      msg := Trim(lines[res[i].Y-1]);
       msg := strutils.ReplaceStr(msg, fToFind, '`' + fToFind + '`');
-      msgs.message(msg, nil, amcMisc, amkInf);
+      msgs.message(format(fmt, [res[i].Y, res[i].X, msg]), nil, amcMisc, amkInf);
     end;
   finally
     search.free;