Wondering what I'm doing wrong?

"David McClain (as dbm at refined-audiometrics dot com)" <[email protected]> Tue, 9 Jun 2026 03:24:50 -0700
Newsgroups gmane.lisp.lispworks.general
Message-ID <[email protected]>
In working with regular expression parsers - both in LW and with CL-PPCRE - I find it odd that there is no way to refer to sub-patterns, by name, from within the pattern strings. You *can* do this by writing out CL-PPCRE parse trees by hand. But not embedded within regexp pattern strings.

I have never used Perl, but looking around on the web, I found the "(?&<name>)” syntax, along with DEFINE, mentioned for this purpose. So I went ahead and added that syntax to the string parser in my copy of CL-PPCRE so that I can write:

------------------------------------
(defmacro ltv-scanner (str)
  `(load-time-value
    (cl-ppcre:create-scanner ,str)
    t))

(eval-always
  (defmacro def-lexical-synonym (name arg)
    `(cl-ppcre:define-parse-tree-synonym ,name ,(if (stringp arg)
                                                    (cl-ppcre:parse-string arg)
                                                  arg))))

(def-lexical-synonym sign     "[-+]")
(def-lexical-synonym digit    "[0-9]")

(def-lexical-synonym digits   "(?&digit)+")
(def-lexical-synonym nn4      "(?&digit){4}")
(def-lexical-synonym nn1or2   "(?&digit){1,2}")
(def-lexical-synonym frac     "\\.(?&digits)")

(def-lexical-synonym ts-date  "((?&nn4))/((?&nn1or2))/((?&nn1or2))")
(def-lexical-synonym ts-time  "[Tt]((?&nn1or2)):((?&nn1or2)):((?&nn1or2)(?&frac)?)")
(def-lexical-synonym ts-tz    "([Uu]((?&sign)(?&nn1or2))?)")

(defun convert-utc-date (s)
  (cl-ppcre:register-groups-bind (yyyy mo dd hh mm ss tztail tz)
      ((ltv-scanner "^(?&ts-date)(?&ts-time)?(?&ts-tz)?$”) ;; optional time and tz info
       s :sharedp t)
    (let* ((yr  (read-from-string yyyy))
           (mon (read-from-string mo))
           (day (read-from-string dd))
           (hrs (if hh
                    (read-from-string hh)
                  0))
		...
————————————

But I’m wondering why these omissions? Is there a better way to proceed than by stringing together a bunch of sub-patterns for a match? 

Perhaps a clever cascade of sub-pattern matching? I tried doing that, but it seemed much more complicated in the go/no-go decision logic for deciding whether a string matches the overall pattern.

What am I missing?

 - DM