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