Skip to content

Support backreferences  #43

@jjttjj

Description

@jjttjj

As discussed on the lambdaisland channel of the clojurians slack (https://clojurians.slack.com/archives/C1DV21X9P/p1643329544995089)

I'm trying to replicate this in regal using a backrefernce to match any 3 or more of the same consecutive character:

;;=> ["1111" "1"]```

But can't seem to get it:
```(regal/regex
  [:cat [:capture  :any] [:repeat ::_ 3 nil]]
  {:resolver (fn [x] "\\1")})

;;=>  #"(.)(?:\\1){3,}"

(regal/regex
  [:capture [:capture  :any] [:repeat ::_ 3 nil]]
  {:resolver (fn [x] "\1")})

;;=> #"((.){3,})"


(regal/regex
  [:capture [:capture  :any] [:repeat ::_ 3 nil]]
  {:resolver (fn [x] "\\\\1")})

;;=> #"((.)(?:\\\\1){3,})"```

Any tips?

@plexus Responded:

(ns repl-sessions.poke
  (:require [lambdaisland.regal :as regal]
            [lambdaisland.regal.parse :as regal-parse]))

(regal-parse/parse #"(.)\1{3,}")
;; => [:cat
;;     [:capture :any]
;;     [:repeat [:lambdaisland.regal.parse/not-implemented [:BackReference "1"]] 3]]

backreferences aren't implemented, but seems like a common enough feature that they should be. Would you mind creating a ticket?

here's a workaround you can do yourself:

(defmethod regal/-regal->ir [:ref :common] [[op idx] opts]
  `^::regal/grouped ("\\" ~(str idx)))

(regal/regex
 [:cat
  [:capture  :any]
  [:repeat [:ref 1] 3 nil]])
;; => #"(.)\1{3,}"

It was also questioned if all engines, Java, ECMA, Re2 support this. It looks the like the first two do but Re2 doesn't
google/re2#101

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requesthelp wantedExtra attention is needed

    Type

    No type

    Projects

    Status

    🙈Out of Scope

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions