Migrate from (std pregexp) to (std regex) throughout

ober

01b8c46024d87146cb65f4beace9298101f623cc

diff --git a/gitsafe/allowlist.ss b/gitsafe/allowlist.ss
index ac21ae1..6e0b970 100644
--- a/gitsafe/allowlist.ss
+++ b/gitsafe/allowlist.ss
@@ -14,7 +14,7 @@
                   partition
                   make-date make-time)
            (except (jerboa prelude) meta atom?)
-          (std pregexp)
+          (std regex)
           (std misc ports)
           (std misc string)
           (gitsafe config))
@@ -26,16 +26,15 @@
   ;;   // gitsafe:ignore
   ;;   /* gitsafe:ignore */
 
-  (def *suppress-pat*
-    (pregexp "(?:#|//|/\\*)\\s*gitsafe:ignore(?:=([A-Za-z0-9_-]+))?"))
+  (def *suppress-re*
+    (re "(?:#|//|/\\*)\\s*gitsafe:ignore(?:=([A-Za-z0-9_-]+))?"))
 
   ;; Returns #t if the line is suppressed (optionally for a specific pattern-id symbol).
   (def (line-suppressed? line (pattern-id #f))
-    (let ([m (pregexp-match *suppress-pat* line)])
+    (let ([m (re-search *suppress-re* line)])
       (if (not m)
         #f
-        ;; m = (full-match maybe-pattern-id-group)
-        (let ([specific (and (pair? (cdr m)) (cadr m))])
+        (let ([specific (re-match-group m 1)])
           (cond
             ;; No specific pattern in comment — suppress all
             [(not specific) #t]
diff --git a/gitsafe/git.ss b/gitsafe/git.ss
index f2e5ce1..893fe94 100644
--- a/gitsafe/git.ss
+++ b/gitsafe/git.ss
@@ -24,7 +24,7 @@
                   partition
                   make-date make-time)
            (except (jerboa prelude) meta atom?)
-          (std pregexp)
+          (std regex)
           (std misc process)
           (std misc string)
           (std misc ports))
@@ -66,6 +66,9 @@
   ;; --- Parse unified diff format ---
   ;; Returns list of diff-hunk structs from a git diff output string.
   ;; Only captures added lines (lines starting with +, not +++).
+  (def *hunk-header-re*
+    (re "^@@ -[0-9,]+ \\+([0-9]+)(?:,[0-9]+)? @@"))
+
   (def (parse-unified-diff diff-text current-file)
     (let loop ([lines (string-split diff-text #\newline)]
                [hunks '()]
@@ -81,11 +84,10 @@
               [rest (cdr lines)])
           (cond
             ;; Hunk header: @@ -old,count +new,count @@
-            [(pregexp-match "^@@ -[0-9,]+ \\+([0-9]+)(?:,[0-9]+)? @@" line)
+            [(re-search *hunk-header-re* line)
              =>
              (lambda (m)
-               (let* ([start-str (cadr m)]
-                      [new-start (string->number start-str)]
+               (let* ([new-start (string->number (re-match-group m 1))]
                       ;; Save previous hunk if it had findings
                       [hunks* (if (and cur-hunk
                                        (not (null? (diff-hunk-lines cur-hunk))))
diff --git a/gitsafe/patterns.ss b/gitsafe/patterns.ss
index 39af509..54a5622 100644
--- a/gitsafe/patterns.ss
+++ b/gitsafe/patterns.ss
@@ -20,7 +20,7 @@
                   partition
                   make-date make-time)
            (except (jerboa prelude) meta atom?)
-          (std pregexp))
+          (std regex))
 
   ;; --- Secret pattern struct ---
   (defstruct secret-pattern
@@ -58,13 +58,16 @@
                     (let ([p (/ (inexact c) n)])
                       (loop (+ i 1) (- e (* p (log p 2))))))))))))))
 
+  (def *placeholder-re*
+    (re "(?i:(?:^|[_.-])(?:example|placeholder|dummy|sample|your[_-]?(?:api[_-]?)?key|replace[_-]?me|change[_-]?me|insert[_-]?here)(?:$|[_.-]))"))
+
   (def (not-placeholder? str)
     ;; Reject common test/example placeholder strings.
     ;; Only match placeholder words at word boundaries (start/end or separator)
     ;; to avoid rejecting real secrets that happen to contain "test" or "fake".
-    (not (or (pregexp-match "^[Xx]+$" str)
-             (pregexp-match "^[Aa]+$" str)
-             (pregexp-match "(?i:(?:^|[_.-])(?:example|placeholder|dummy|sample|your[_-]?(?:api[_-]?)?key|replace[_-]?me|change[_-]?me|insert[_-]?here)(?:$|[_.-]))" str)
+    (not (or (re-match? "[Xx]+" str)
+             (re-match? "[Aa]+" str)
+             (re-search *placeholder-re* str)
              (string=? str "")
              (< (string-length str) 8))))
 
@@ -75,7 +78,7 @@
       'aws-access-key
       "AWS Access Key ID"
       'critical
-      (pregexp "(?:^|[^A-Za-z0-9])((?:AKIA|ABIA|ACCA|ASIA)[A-Z0-9]{16})(?:[^A-Za-z0-9]|$)")
+      (re "(?:^|[^A-Za-z0-9])((?:AKIA|ABIA|ACCA|ASIA)[A-Z0-9]{16})(?:[^A-Za-z0-9]|$)")
       (lambda (m) (= (string-length m) 20))
       "AWS IAM Access Key ID (starts with AKIA/ABIA/ACCA/ASIA)"))
 
@@ -84,7 +87,7 @@
       'aws-secret-key
       "AWS Secret Access Key"
       'critical
-      (pregexp "(?i:aws[_-]?secret[_-]?(?:access[_-]?)?key|secret[_-]?key)\\s*[=:]\\s*['\"]?([A-Za-z0-9/+=]{40})['\"]?")
+      (re "(?i:aws[_-]?secret[_-]?(?:access[_-]?)?key|secret[_-]?key)\\s*[=:]\\s*['\"]?([A-Za-z0-9/+=]{40})['\"]?")
       (lambda (m) (= (string-length m) 40))
       "AWS Secret Access Key (40-char base64)"))
 
@@ -93,7 +96,7 @@
       'github-pat
       "GitHub Personal Access Token"
       'critical
-      (pregexp "gh[pousr]_[A-Za-z0-9_]{36,255}")
+      (re "gh[pousr]_[A-Za-z0-9_]{36,255}")
       (lambda (m) (has-prefix? m "gh"))
       "GitHub PAT (classic: ghp_, gho_, ghu_, ghs_, ghr_)"))
 
@@ -102,7 +105,7 @@
       'github-fine-grained
       "GitHub Fine-Grained PAT"
       'critical
-      (pregexp "github_pat_[A-Za-z0-9_]{22,255}")
+      (re "github_pat_[A-Za-z0-9_]{22,255}")
       #f
       "GitHub Fine-Grained Personal Access Token"))
 
@@ -111,7 +114,7 @@
       'openai-api-key
       "OpenAI API Key"
       'critical
-      (pregexp "sk-[A-Za-z0-9]{20}T3BlbkFJ[A-Za-z0-9]{20}")
+      (re "sk-[A-Za-z0-9]{20}T3BlbkFJ[A-Za-z0-9]{20}")
       (lambda (m) (string-contains m "T3BlbkFJ"))
       "OpenAI API Key (contains T3BlbkFJ marker)"))
 
@@ -120,7 +123,7 @@
       'openai-project-key
       "OpenAI Project Key"
       'critical
-      (pregexp "sk-proj-[A-Za-z0-9_-]{40,200}")
+      (re "sk-proj-[A-Za-z0-9_-]{40,200}")
       #f
       "OpenAI Project-scoped API Key"))
 
@@ -129,7 +132,7 @@
       'anthropic-api-key
       "Anthropic API Key"
       'critical
-      (pregexp "sk-ant-(?:[a-z0-9]+-)?[A-Za-z0-9_-]{80,200}")
+      (re "sk-ant-(?:[a-z0-9]+-)?[A-Za-z0-9_-]{80,200}")
       (lambda (m) (has-prefix? m "sk-ant-"))
       "Anthropic Claude API Key"))
 
@@ -138,7 +141,7 @@
       'openai-svcacct-key
       "OpenAI Service Account Key"
       'critical
-      (pregexp "sk-svcacct-[A-Za-z0-9_-]{40,200}")
+      (re "sk-svcacct-[A-Za-z0-9_-]{40,200}")
       #f
       "OpenAI Service Account API Key"))
 
@@ -147,7 +150,7 @@
       'stripe-secret
       "Stripe Secret Key"
       'critical
-      (pregexp "[sr]k_live_[A-Za-z0-9]{24,99}")
+      (re "[sr]k_live_[A-Za-z0-9]{24,99}")
       #f
       "Stripe live secret or restricted key"))
 
@@ -156,7 +159,7 @@
       'private-key-pem
       "Private Key (PEM)"
       'critical
-      (pregexp "-----BEGIN (?:RSA |DSA |EC |OPENSSH |PGP |ENCRYPTED )?PRIVATE KEY-----")
+      (re "-----BEGIN (?:RSA |DSA |EC |OPENSSH |PGP |ENCRYPTED )?PRIVATE KEY-----")
       #f
       "PEM-encoded private key block"))
 
@@ -165,7 +168,7 @@
       'putty-private-key
       "PuTTY Private Key"
       'critical
-      (pregexp "PuTTY-User-Key-File-[0-9]+:")
+      (re "PuTTY-User-Key-File-[0-9]+:")
       #f
       "PuTTY PPK private key file"))
 
@@ -176,7 +179,7 @@
       'generic-api-key
       "Generic API Key Assignment"
       'high
-      (pregexp "(?i:(api[_-]?key|apikey|api[_-]?secret|access[_-]?key))\\s*[=:]\\s*['\"]([A-Za-z0-9_/+=.\\-]{16,})['\"]")
+      (re "(?i:(api[_-]?key|apikey|api[_-]?secret|access[_-]?key))\\s*[=:]\\s*['\"]([A-Za-z0-9_/+=.\\-]{16,})['\"]")
       (lambda (m) (and (not-placeholder? m) (entropy-above? m 3.5)))
       "Key/value assignment with high-entropy value"))
 
@@ -185,7 +188,7 @@
       'generic-secret
       "Generic Secret Assignment"
       'high
-      (pregexp "(?i:(secret|token|password|passwd|credential|auth[_-]?key))\\s*[=:]\\s*['\"]([^'\"\\s]{8,})['\"]")
+      (re "(?i:(secret|token|password|passwd|credential|auth[_-]?key))\\s*[=:]\\s*['\"]([^'\"\\s]{8,})['\"]")
       (lambda (m) (and (not-placeholder? m) (entropy-above? m 3.5)))
       "Assignment of secret/token/password with high-entropy value"))
 
@@ -194,7 +197,7 @@
       'generic-bearer
       "Bearer Token"
       'high
-      (pregexp "(?i:bearer)\\s+([A-Za-z0-9_.~+/=\\-]{20,})")
+      (re "(?i:bearer)\\s+([A-Za-z0-9_.~+/=\\-]{20,})")
       (lambda (m) (entropy-above? m 3.0))
       "HTTP Authorization Bearer token"))
 
@@ -203,7 +206,7 @@
       'slack-token
       "Slack Token"
       'high
-      (pregexp "xox[bpors]-[A-Za-z0-9\\-]{10,250}")
+      (re "xox[bpors]-[A-Za-z0-9\\-]{10,250}")
       #f
       "Slack API token (xoxb-, xoxp-, xoxo-, xoxr-, xoxs-)"))
 
@@ -212,7 +215,7 @@
       'slack-webhook
       "Slack Webhook URL"
       'high
-      (pregexp "hooks\\.slack\\.com/services/T[A-Z0-9]{8,10}/B[A-Z0-9]{8,10}/[A-Za-z0-9]{20,30}")
+      (re "hooks\\.slack\\.com/services/T[A-Z0-9]{8,10}/B[A-Z0-9]{8,10}/[A-Za-z0-9]{20,30}")
       #f
       "Slack incoming webhook URL"))
 
@@ -221,7 +224,7 @@
       'google-api-key
       "Google API Key"
       'high
-      (pregexp "AIza[A-Za-z0-9_\\-]{35}")
+      (re "AIza[A-Za-z0-9_\\-]{35}")
       (lambda (m) (= (string-length m) 39))
       "Google Cloud / Maps API key (starts with AIza)"))
 
@@ -230,7 +233,7 @@
       'twilio-api-key
       "Twilio API Key"
       'high
-      (pregexp "SK[a-f0-9]{32}")
+      (re "SK[a-f0-9]{32}")
       (lambda (m) (= (string-length m) 34))
       "Twilio API key SID"))
 
@@ -239,7 +242,7 @@
       'sendgrid-api-key
       "SendGrid API Key"
       'high
-      (pregexp "SG\\.[A-Za-z0-9_\\-]{22}\\.[A-Za-z0-9_\\-]{43}")
+      (re "SG\\.[A-Za-z0-9_\\-]{22}\\.[A-Za-z0-9_\\-]{43}")
       #f
       "SendGrid API key (SG. format)"))
 
@@ -248,7 +251,7 @@
       'mailgun-api-key
       "Mailgun API Key"
       'high
-      (pregexp "key-[a-f0-9]{32}")
+      (re "key-[a-f0-9]{32}")
       (lambda (m) (= (string-length m) 36))
       "Mailgun private API key"))
 
@@ -257,7 +260,7 @@
       'npm-token
       "NPM Token"
       'high
-      (pregexp "npm_[A-Za-z0-9]{36}")
+      (re "npm_[A-Za-z0-9]{36}")
       #f
       "NPM publish/automation token"))
 
@@ -266,7 +269,7 @@
       'pypi-token
       "PyPI Token"
       'high
-      (pregexp "pypi-[A-Za-z0-9_\\-]{50,}")
+      (re "pypi-[A-Za-z0-9_\\-]{50,}")
       #f
       "PyPI upload token"))
 
@@ -275,19 +278,20 @@
       'jwt
       "JSON Web Token"
       'high
-      (pregexp "eyJ[A-Za-z0-9_\\-]{10,}\\.[A-Za-z0-9_\\-]{10,}\\.[A-Za-z0-9_\\-]{10,}")
+      (re "eyJ[A-Za-z0-9_\\-]{10,}\\.[A-Za-z0-9_\\-]{10,}\\.[A-Za-z0-9_\\-]{10,}")
       #f
       "JWT (three-part base64url token starting with eyJ)"))
 
+  (def *basic-auth-placeholder-re*
+    (re "(?i://(?:user|username|admin|root):(?:pass|password|passwd|secret|changeme|x{3,})@)"))
+
   (def pat-basic-auth-url
     (make-secret-pattern
       'basic-auth-url
       "Credentials in URL"
       'high
-      (pregexp "[a-z+]+://[^:@\\s]+:[^:@\\s]+@[^\\s\"']+")
-      (lambda (m) (not (pregexp-match
-                         "(?i://(?:user|username|admin|root):(?:pass|password|passwd|secret|changeme|x{3,})@)"
-                         m)))
+      (re "[a-z+]+://[^:@\\s]+:[^:@\\s]+@[^\\s\"']+")
+      (lambda (m) (not (re-search *basic-auth-placeholder-re* m)))
       "URL with embedded user:password credentials"))
 
   ;; --- MEDIUM patterns ---
@@ -297,7 +301,7 @@
       'connection-string
       "Database Connection String"
       'medium
-      (pregexp "(?i:(?:mongodb|postgres|postgresql|mysql|redis|amqp|mssql))://[^:@\\s]+:[^:@\\s]+@[^\\s\"']+")
+      (re "(?i:(?:mongodb|postgres|postgresql|mysql|redis|amqp|mssql))://[^:@\\s]+:[^:@\\s]+@[^\\s\"']+")
       #f
       "Database/broker connection string with credentials"))
 
@@ -306,7 +310,7 @@
       'high-entropy-hex
       "High-Entropy Hex String"
       'medium
-      (pregexp "[0-9a-f]{40,}")
+      (re "[0-9a-f]{40,}")
       (lambda (m) (entropy-above? m 3.0))
       "Long hex string with high entropy (possible API key or token)"))
 
@@ -315,7 +319,7 @@
       'high-entropy-base64
       "High-Entropy Base64 String"
       'medium
-      (pregexp "[A-Za-z0-9+/]{40,}={0,2}")
+      (re "[A-Za-z0-9+/]{40,}={0,2}")
       (lambda (m) (entropy-above? m 4.0))
       "Long base64 string with high entropy (possible encoded secret)"))
 
diff --git a/gitsafe/scanner.ss b/gitsafe/scanner.ss
index 92824c4..8582d46 100644
--- a/gitsafe/scanner.ss
+++ b/gitsafe/scanner.ss
@@ -27,7 +27,7 @@
                   partition
                   make-date make-time)
            (except (jerboa prelude) meta atom?)
-          (std pregexp)
+          (std regex)
           (std misc string)
           (std misc ports)
           (std os path)
@@ -81,6 +81,33 @@
                (config-excluded? config path))
            #t)))
 
+  ;; --- Compiled patterns ---
+  (def *hunk-header-re*
+    (re "^@@ -[0-9,]+ \\+([0-9]+)(?:,[0-9]+)? @@"))
+
+  ;; --- URL context detection ---
+  ;; Pattern IDs whose matches should be suppressed when they appear inside a URL.
+  ;; These are the noisy entropy patterns; precise patterns (AWS keys, GitHub PATs,
+  ;; etc.) are intentionally excluded so credentials embedded in URLs are still caught.
+  (def *url-sensitive-patterns*
+    '(high-entropy-base64 high-entropy-hex))
+
+  ;; Returns #t if the position match-start in line follows a "://" sequence,
+  ;; indicating the match is part of a URL path, query string, or fragment.
+  ;; Looks back up to 300 chars to handle long URLs before the match.
+  (def (in-url-context? line match-start)
+    (let ([limit (string-length line)])
+      (let loop ([i (max 0 (- match-start 300))])
+        (cond
+          ;; Need at least 3 chars "://" before match-start
+          [(>= (+ i 2) match-start) #f]
+          [(and (< (+ i 2) limit)
+                (char=? (string-ref line i) #\:)
+                (char=? (string-ref line (+ i 1)) #\/)
+                (char=? (string-ref line (+ i 2)) #\/))
+           #t]
+          [else (loop (+ i 1))]))))
+
   ;; --- Severity ordering ---
   (def (severity-level sev)
     (match sev
@@ -97,21 +124,19 @@
   (def (min-severity config)
     (gitsafe-config-severity config))
 
-  ;; --- Extract matched substring from pregexp-match-positions result ---
-  (def (extract-match line positions)
-    ;; positions is ((start . end) ...) — first pair is the full match,
-    ;; rest are capture groups.  Use the last non-#f capture group if any,
-    ;; so validators receive the meaningful value (e.g. the key itself)
-    ;; rather than the full match including boundary/context chars.
-    (and (pair? positions)
-         (let* ([best (let loop ([rest (cdr positions)] [last-good #f])
-                        (cond
-                          [(null? rest) (or last-good (car positions))]
-                          [(car rest)   (loop (cdr rest) (car rest))]
-                          [else         (loop (cdr rest) last-good)]))]
-                [s (car best)]
-                [e (cdr best)])
-           (substring line s e))))
+  ;; --- Extract matched substring from a re-match-object ---
+  (def (extract-match m)
+    ;; Use the last non-#f capture group if any, so validators receive
+    ;; the meaningful value (e.g. the key itself) rather than the full
+    ;; match including boundary/context chars.
+    (let ([groups (re-match-groups m)])
+      (if (null? groups)
+        (re-match-full m)
+        (let loop ([gs groups] [last-good #f])
+          (cond
+            [(null? gs) (or last-good (re-match-full m))]
+            [(car gs)   (loop (cdr gs) (car gs))]
+            [else       (loop (cdr gs) last-good)])))))
 
   ;; --- Get active patterns given config ---
   (def (active-patterns config)
@@ -132,15 +157,18 @@
         (if (null? pats)
           (reverse results)
           (let ([pat (car pats)])
-            (let ([positions (pregexp-match-positions
-                               (secret-pattern-pregexp pat) line)])
-              (if (not positions)
+            (let ([m (re-search (secret-pattern-pregexp pat) line)])
+              (if (not m)
                 (loop (cdr pats) results)
-                (let ([matched (extract-match line positions)])
+                (let ([matched (extract-match m)])
                   (if (not matched)
                     (loop (cdr pats) results)
-                    ;; Run validator if present
-                    (let ([valid? (let ([v (secret-pattern-validator pat)])
+                    ;; For high-noise entropy patterns, suppress matches inside URLs
+                    (if (and (member (secret-pattern-id pat) *url-sensitive-patterns*)
+                             (in-url-context? line (re-match-start m)))
+                      (loop (cdr pats) results)
+                      ;; Run validator if present
+                      (let ([valid? (let ([v (secret-pattern-validator pat)])
                                     (if v (v matched) #t))])
                       (if (not valid?)
                         (loop (cdr pats) results)
@@ -160,7 +188,7 @@
                                        (redact line)
                                        matched
                                        (redact matched))])
-                              (loop (cdr pats) (cons f results))))))))))
+                              (loop (cdr pats) (cons f results)))))))))))
           ))))))
 
   ;; --- Scan full file content (string) ---
@@ -248,10 +276,10 @@
         (let ([line (car lines)]
               [rest (cdr lines)])
           (cond
-            [(pregexp-match "^@@ -[0-9,]+ \\+([0-9]+)(?:,[0-9]+)? @@" line)
+            [(re-search *hunk-header-re* line)
              =>
              (lambda (m)
-               (let* ([new-start (string->number (cadr m))]
+               (let* ([new-start (string->number (re-match-group m 1))]
                       [hunks* (if (and cur-hunk
                                        (not (null? (diff-hunk-lines cur-hunk))))
                                 (cons cur-hunk hunks)
diff --git a/test/fixtures/false-positives.txt b/test/fixtures/false-positives.txt
index a4e01a9..293c03e 100644
--- a/test/fixtures/false-positives.txt
+++ b/test/fixtures/false-positives.txt
@@ -27,3 +27,12 @@ integrity = "sha512-abc123def456"
 
 # Test that gitsafe:ignore suppression works
 secret_key = "sk_live_thisshouldbesuppressed"  # gitsafe:ignore
+
+# URLs in comments — long URL paths look like base64 but are not secrets.
+# These are real examples from Wireshark dissector source files.
+;; https://github.com/couchbase/couchbase-protocol
+;; https://kafka.apache.org/protocol/protocol
+;; https://github.com/wireshark/wireshark/blob/master/epan/dissectors/packet-memcache.c
+;; https://en.wikipedia.org/wiki/RTTRP#History-2ddb12341234abcdef12abcd2cf5
+;; https://sourceforge.net/projects/moldudp64/files/spec/moldudp64.pdf
+;; https://standards.ieee.org/findstds/standard/802.3304-2017.html
diff --git a/test/test-gitsafe.ss b/test/test-gitsafe.ss
index ec53544..0acc686 100644
--- a/test/test-gitsafe.ss
+++ b/test/test-gitsafe.ss
@@ -26,7 +26,7 @@
 
  (import (except (jerboa prelude) meta atom?)
         (std test)
-        (std pregexp)
+        (std regex)
         (gitsafe entropy)
         (gitsafe patterns)
         (gitsafe config)
@@ -102,14 +102,14 @@
       (let ([pat (car (filter (lambda (p) (eq? (secret-pattern-id p) 'aws-access-key))
                               (all-patterns)))])
         (check-predicate
-          (pregexp-match (secret-pattern-pregexp pat) "AKIAIOSFODNN7EXAMPLE!!!")
+          (re-search (secret-pattern-pregexp pat) "AKIAIOSFODNN7EXAMPLE!!!")
           (lambda (m) m))))
 
     (test-case "github-pat: detects ghp_ token"
       (let ([pat (car (filter (lambda (p) (eq? (secret-pattern-id p) 'github-pat))
                               (all-patterns)))])
         (check-predicate
-          (pregexp-match (secret-pattern-pregexp pat)
+          (re-search (secret-pattern-pregexp pat)
                          "ghp_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef1234")
           (lambda (m) m))))
 
@@ -117,7 +117,7 @@
       (let ([pat (car (filter (lambda (p) (eq? (secret-pattern-id p) 'anthropic-api-key))
                               (all-patterns)))])
         (check-predicate
-          (pregexp-match (secret-pattern-pregexp pat)
+          (re-search (secret-pattern-pregexp pat)
                          "sk-ant-api03-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcde")
           (lambda (m) m))))
 
@@ -125,7 +125,7 @@
       (let ([pat (car (filter (lambda (p) (eq? (secret-pattern-id p) 'jwt))
                               (all-patterns)))])
         (check-predicate
-          (pregexp-match (secret-pattern-pregexp pat)
+          (re-search (secret-pattern-pregexp pat)
                          "eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiYWRtaW4ifQ.SflKxwRJSMeKKF2QT4fw")
           (lambda (m) m))))
 
@@ -133,7 +133,7 @@
       (let ([pat (car (filter (lambda (p) (eq? (secret-pattern-id p) 'stripe-secret))
                               (all-patterns)))])
         (check-predicate
-          (pregexp-match (secret-pattern-pregexp pat)
+          (re-search (secret-pattern-pregexp pat)
                          "sk_live_ABCDEFGHIJKLMNOPQRSTUVWXYZabc")
           (lambda (m) m))))
 
@@ -141,7 +141,7 @@
       (let ([pat (car (filter (lambda (p) (eq? (secret-pattern-id p) 'private-key-pem))
                               (all-patterns)))])
         (check-predicate
-          (pregexp-match (secret-pattern-pregexp pat)
+          (re-search (secret-pattern-pregexp pat)
                          "-----BEGIN OPENSSH PRIVATE KEY-----")
           (lambda (m) m))))
 
@@ -149,7 +149,7 @@
       (let ([pat (car (filter (lambda (p) (eq? (secret-pattern-id p) 'private-key-pem))
                               (all-patterns)))])
         (check-predicate
-          (pregexp-match (secret-pattern-pregexp pat)
+          (re-search (secret-pattern-pregexp pat)
                          "-----BEGIN ENCRYPTED PRIVATE KEY-----")
           (lambda (m) m))))
 
@@ -157,7 +157,7 @@
       (let ([pat (car (filter (lambda (p) (eq? (secret-pattern-id p) 'putty-private-key))
                               (all-patterns)))])
         (check-predicate
-          (pregexp-match (secret-pattern-pregexp pat)
+          (re-search (secret-pattern-pregexp pat)
                          "PuTTY-User-Key-File-3: ssh-rsa")
           (lambda (m) m))))
 
@@ -319,6 +319,27 @@
                          c)])
         (check-equal? '() findings)))
 
+    (test-case "scan-content: URLs in comments are not flagged as entropy secrets"
+      ;; Long URL paths match [A-Za-z0-9/]{40+} but are not secrets.
+      (let* ([c        (default-config)]
+             [findings (scan-content "dissectors/kafka.ss"
+                         ";; https://kafka.apache.org/protocol/protocol\n;; https://github.com/couchbase/couchbase-protocol\n;; https://en.wikipedia.org/wiki/RTTRP#History-2ddb12341234abcdef12abcd2cf5\n"
+                         c)])
+        (check-equal? '() (filter (lambda (f)
+                                    (member (finding-pattern-id f)
+                                            '(high-entropy-base64 high-entropy-hex)))
+                                  findings))))
+
+    (test-case "scan-content: false-positives fixture produces no entropy findings"
+      (let* ([c        (default-config)]
+             [content  (read-file-string "test/fixtures/false-positives.txt")]
+             [findings (scan-content "false-positives.txt" content c)]
+             [entropy-findings (filter (lambda (f)
+                                         (member (finding-pattern-id f)
+                                                 '(high-entropy-base64 high-entropy-hex)))
+                                       findings)])
+        (check-equal? '() entropy-findings)))
+
   ))
 
 ;; ============================================================