common-lispsbclcl-ppcre

Extracting a regex match in common lisp


I must be missing something very basic here.

I need to extract a capture group from a match in common lisp. When I eval in the interpreter (an sbcl implementation):

`(cl-ppcre::scan-to-strings ".*?(\\d).png" "sample1.png")`

I get:

"sample1.png"
#("1")

But if I bind that expression to a value, say

`(setq number (cl-ppcre::scan-to-strings ".*(\\d).png" "sample1.png"))`

The value of number is becomes "sample1.png". How do I get the "1", which is printed?


Solution

  • Your question

    You are looking for

    (setf (values match position) 
          (cl-ppcre::scan-to-strings ".*(\\d).png" "sample1.png"))
    

    See also multiple-value-bind et al.

    Under the hood

    Common lisp functions can return multiple values. This corresponds to "tuple" return value in other languages, such as Python. So, when a lisp function, such as floor, return multiple values, a Python user will write something like

    (f,r) = floor(10,3)
    

    and floor will (usually) allocate a tuple, which is captured when you write fr = floor(10,3).

    CL multiple values do not allocate extra storage, but the extra values are discarded unless you specifically ask for them:

    (setf (values f r) (floor 10 3))
    

    will capture both values, but (setf f (floor 10 3)) will discard r.