Issue with emacs regular expression

Viewed 85

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
2 Answers

You could make the first group non greedy and add an anchor after the second optional group

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

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
Related