Search code examples
regexemacselisp

Issue with emacs regular expression


I'm having issue with the following code, not sure how else I can write it

(defun padname (strg)
  (string-match "[uU]_\\(.*\\)\\(_[0-9\]+\\)?" strg)
    (match-string 1 strg)
)

(padname "u_CLR_REQ_SUP_00")
"CLR_REQ_SUP_00" ==> expect "CLR_REQ_SUP"
(padname "u_CLR_REQ_SUP_0")
"CLR_REQ_SUP_0"  ==> expect "CLR_REQ_SUP"
(padname "u_PTO_AVDD_3P3_0")
"PTO_AVDD_3P3_0"  ==> expect "PTO_AVDD_3P3"
(padname "u_PTO_0")
"PTO_0"  ==> expect "PTO"
(padname "u_PTO")
"PTO" ==> as expected
(padname "u_BTNI")
"BTNI" ==> as expected

Solution

  • Another variation, use greedy dot with [^0-9_][0-9]* at the end to stop at last non-digit with any digits after and combine with the optional group:

    [Uu]_\\(.*[^0-9_][0-9]*\\)\\(_[0-9]+\\)?$
    

    See regex proof.

    EXPLANATION

    --------------------------------------------------------------------------------
      [Uu]                     any character of: 'U', 'u'
    --------------------------------------------------------------------------------
      _                        '_'
    --------------------------------------------------------------------------------
      (                        group and capture to \1:
    --------------------------------------------------------------------------------
        .*                       any character except \n (0 or more times
                                 (matching the most amount possible))
    --------------------------------------------------------------------------------
        [^0-9_]                  any character except: '0' to '9', '_'
    --------------------------------------------------------------------------------
        [0-9]*                   any character of: '0' to '9' (0 or more
                                 times (matching the most amount
                                 possible))
    --------------------------------------------------------------------------------
      )                        end of \1
    --------------------------------------------------------------------------------
      (                        group and capture to \2 (optional
                               (matching the most amount possible)):
    --------------------------------------------------------------------------------
        _                        '_'
    --------------------------------------------------------------------------------
        [0-9]+                   any character of: '0' to '9' (1 or more
                                 times (matching the most amount
                                 possible))
    --------------------------------------------------------------------------------
      )?                       end of \2 (NOTE: because you are using a
                               quantifier on this capture, only the LAST
                               repetition of the captured pattern will be
                               stored in \2)
    --------------------------------------------------------------------------------
      $                        before an optional \n, and the end of the
                               string