Author Topic: Using wcmatch to filter numerical strings, some examples...  (Read 6445 times)

0 Members and 1 Guest are viewing this topic.

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Using wcmatch to filter numerical strings, some examples...
« on: October 27, 2010, 04:29:07 PM »
This post got me thinking about using wcmatch to identify numerical strings. The advantage of using only wcmatch is that it can be used in a filter for the ssget function. Of course wcmatch doesn't have the options of regular expressions. But with multiple calls and creative use of the tilde, you can filter for numerical strings.

Example:
Code: [Select]
(wcmatch str "~*~#*") ; match positive integer
Code: [Select]
(defun kg:StringIsNum? (str)
  (and
    (wcmatch str "~*[~-.0-9]*") ; only minus signs, decimal points and numbers allowed
    (wcmatch str "~*`.*`.*")    ; only one decimal point allowed
    (or
      (wcmatch str "~*-*")      ; there is no minus sign
      (and
        (wcmatch str "-*")      ; the minus sign must be the first character
        (wcmatch str "~*-*-*")  ; only one minus sign allowed
      )
    )
  )
)

(defun kg:StringIsInt? (str)
  (and
    (wcmatch str "~*[~-0-9]*")  ; only minus signs and numbers allowed
    (or
      (wcmatch str "~*-*")      ; there is no minus sign
      (and
        (wcmatch str "-*")      ; the minus sign must be the first character
        (wcmatch str "~*-*-*")  ; only one minus sign allowed
      )
    )
  )
)

(defun kg:StringIsReal? (str)
  (and
    (wcmatch str "~*[~-.0-9]*") ; only minus signs, decimal points and numbers allowed
    (wcmatch str "*`.*")        ; there must be one decimal point
    (wcmatch str "~*`.*`.*")    ; only one decimal point allowed
    (or
      (wcmatch str "~*-*")      ; there is no minus sign
      (and
        (wcmatch str "-*")      ; the minus sign must be the first character
        (wcmatch str "~*-*-*")  ; only one minus sign allowed
      )
    )
  )
)

(defun kg:SsgetFilterNum ()
  '(
    (1 . "~*[~-.0-9]*") ; only minus signs, decimal points and numbers allowed
    (1 . "~*`.*`.*")    ; only one decimal point allowed
    (-4 . "<OR")
      (1 . "~*-*")      ; there is no minus sign
      (-4 . "<AND")
        (1 . "-*")      ; the minus sign must be the first character
        (1 . "~*-*-*")  ; only one minus sign allowed
      (-4 . "AND>")
    (-4 . "OR>")
  )
)

(defun kg:SsgetFilterInt ()
  '(
    (1 . "~*[~-0-9]*")  ; only minus signs and numbers allowed
    (-4 . "<OR")
      (1 . "~*-*")      ; there is no minus sign
      (-4 . "<AND")
        (1 . "-*")      ; the minus sign must be the first character
        (1 . "~*-*-*")  ; only one minus sign allowed
      (-4 . "AND>")
    (-4 . "OR>")
  )
)

(defun kg:SsgetFilterReal ()
  '(
    (1 . "~*[~-.0-9]*") ; only minus signs, decimal points and numbers allowed
    (1 . "*`.*")        ; there must be one decimal point
    (1 . "~*`.*`.*")    ; only one decimal point allowed
    (-4 . "<OR")
      (1 . "~*-*")      ; there is no minus sign
      (-4 . "<AND")
        (1 . "-*")      ; the minus sign must be the first character
        (1 . "~*-*-*")  ; only one minus sign allowed
      (-4 . "AND>")
    (-4 . "OR>")
  )
)

Comp function using kg:SsgetFilterInt (based on CAB's code in the already mentioned post):
Code: [Select]
(defun Comp (/ ent ss i lst)
  (if
    (and
      (setq ent (entsel "\nPlease select a text for style, layer and text height filtering: "))
      (setq ent (entget (car ent)))
      (or
        (equal '(0 . "TEXT") (assoc 0 ent))
        (prompt "\nNot a text ")
      )
      (or
        (setq ss
          (ssget
            "_X"
            (vl-list*
              '(0 . "TEXT")
              (assoc 7 ent)        ; style of digit text
              (assoc 8 ent)        ; selected layer name
              (assoc 40 ent)       ; selected text height
              (assoc 410 ent)      ; current tab only
              ;; numerical text filtering:
              (kg:SsgetFilterInt)
            )
          )
        )
        (prompt "\nNo selection ")
      )
    )
    (mapcar
      '(lambda (a) (cdr (assoc 1 (entget a))))
      (repeat (setq i (sslength ss))
        (setq lst (cons (ssname ss (setq i (1- i))) lst))
      )
    )
  )
)

No doubt some of you have even better ideas! :wink:

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Using wcmatch to filter numerical strings, some examples...
« Reply #2 on: October 28, 2010, 04:16:18 AM »
More food for thought. :)
Indeed!

Working in the metric system I always use atof instead of distof and didn't even know that distof returns nil on a non-numerical string! I am learning something new every day here! :wink: