Author Topic: Reverse a string of text  (Read 6406 times)

0 Members and 1 Guest are viewing this topic.

Hangman

  • Swamp Rat
  • Posts: 566
Reverse a string of text
« on: February 01, 2011, 11:41:05 AM »
Morn'n all,

I am just curious as I have a couple drawings with labels that are reversed and it got me thinking, is there a simple code to reverse a string of text?

For example, the current label is "A15", or "AC015", or for a worst case scenario, a label for a fuse "FUSE F12", or "F12 125MA 24VDC".  You want the label(s) to read "15A", or "015AC", and for the worst case scenario, the label would read "FUSE 12F", or "12F 125MA 24VDC".
Granted for the worst case scenario, it would be extensive code to search for the fuse label in a string such as this, so you are not reversing the voltage or amperage, but the label only.

But to quench the curiosity without losing a life, has anyone put a piece of code together to reverse a string of text?

Any thoughts, ... suggestions, ...  perhaps a challenge for the guru's?.     :wink:
Hangman  8)

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Drafting Board, Mechanical Arm, KOH-I-NOOR 0.7mm
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Reverse a string of text
« Reply #1 on: February 01, 2011, 11:42:21 AM »
Code: [Select]
(vl-list->string (reverse (vl-string->list <string>)))

deegeecees

  • Guest
Re: Reverse a string of text
« Reply #2 on: February 01, 2011, 11:54:45 AM »
That would require some conditional boolean magic.

Hangman

  • Swamp Rat
  • Posts: 566
Re: Reverse a string of text
« Reply #3 on: February 01, 2011, 11:56:01 AM »
Code: [Select]
(vl-list->string (reverse (vl-string->list <string>)))

LOL !!!
Fine ..., for you Lee, you have to do the worst case scenario.   :D
Reverse the label for the following strings:
Quote
"FUSE A7 2A 24VDC" to read "FUSE 7A 2A 24VDC".
"FUSE A12 1A 12VDC" to read "FUSE 12A 1A 12VDC".

I can't think, somebody engineer a nearly impossible string for Lee to decipher   :P
Hangman  8)

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Drafting Board, Mechanical Arm, KOH-I-NOOR 0.7mm
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Hangman

  • Swamp Rat
  • Posts: 566
Re: Reverse a string of text
« Reply #4 on: February 01, 2011, 11:57:41 AM »
That would require some conditional boolean magic.

Ooooh, Boooolean!  K, keep talk'n ...
Hangman  8)

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Drafting Board, Mechanical Arm, KOH-I-NOOR 0.7mm
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Reverse a string of text
« Reply #5 on: February 01, 2011, 12:00:59 PM »
Code: [Select]
(vl-list->string (reverse (vl-string->list <string>)))

LOL !!!
Fine ..., for you Lee, you have to do the worst case scenario.   :D
Reverse the label for the following strings:
Quote
"FUSE A7 2A 24VDC" to read "FUSE 7A 2A 24VDC".
"FUSE A12 1A 12VDC" to read "FUSE 12A 1A 12VDC".

I can't think, somebody engineer a nearly impossible string for Lee to decipher   :P

 :-D  Will post something later, going out for now  :-)

deegeecees

  • Guest
Re: Reverse a string of text
« Reply #6 on: February 01, 2011, 12:24:29 PM »
That would require some conditional boolean magic.

Ooooh, Boooolean!  K, keep talk'n ...


If you have predetermined conditions then you could run it through a COND wringer.Don't have time to write it out atm tho.

Matt__W

  • Seagull
  • Posts: 12955
  • I like my water diluted.
Re: Reverse a string of text
« Reply #7 on: February 01, 2011, 12:41:14 PM »
Code: [Select]
(vl-list->string (reverse (vl-string->list <string>)))

LOL !!!
Fine ..., for you Lee, you have to do the worst case scenario.   :D
Reverse the label for the following strings:
Quote
"FUSE A7 2A 24VDC" to read "FUSE 7A 2A 24VDC".
"FUSE A12 1A 12VDC" to read "FUSE 12A 1A 12VDC".

I can't think, somebody engineer a nearly impossible string for Lee to decipher   :P
What if you try to reverse the word RADAR?  Will the computer blow up?   :-D
Autodesk Expert Elite
Revit Subject Matter Expert (SME)
Owner/FAA sUAS Pilot @ http://skyviz.io

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Reverse a string of text
« Reply #8 on: February 01, 2011, 12:46:31 PM »
Simple enough.
Break the string using space char
If a component ends with a number char put the numbers in front.
Put the string back together

 8-)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

Guitar_Jones

  • Guest
Re: Reverse a string of text
« Reply #9 on: February 01, 2011, 12:47:07 PM »
Quote
What if you try to reverse the word RADAR?  Will the computer blow up?
a man a plan a canal panama   :lmao:

alanjt

  • Needs a day job
  • Posts: 5352
  • Standby for witty remark...
Re: Reverse a string of text
« Reply #10 on: February 01, 2011, 02:10:16 PM »
Quote
What if you try to reverse the word RADAR?  Will the computer blow up?
a man a plan a canal panama   :lmao:
:lol:
Civil 3D 2019 ~ Windohz 7 64bit
Dropbox

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Reverse a string of text
« Reply #11 on: February 01, 2011, 03:37:29 PM »
Feeling lazy so just using CAB's proposed method with a couple of pre-written subs from my site...

Code: [Select]
(defun ReverseTag ( string )
  (LM:lst->str
    (mapcar
      (function
        (lambda ( x )
          (if (wcmatch x "*#")
            (vl-list->string (reverse (vl-string->list x)))
            x
          )
        )
      )
      (LM:str->lst string " ")
    )
    " "
  )
)

(defun LM:str->lst ( str del / pos ) (vl-load-com)
  ;; © Lee Mac 2010
  (if (setq pos (vl-string-search del str))
    (cons (substr str 1 pos) (LM:str->lst (substr str (+ pos 1 (strlen del))) del))
    (list str)
  )
)

(defun LM:lst->str ( lst del )
  ;; © Lee Mac 2010
  (if (cdr lst)
    (strcat (car lst) del (LM:lst->str (cdr lst) del))
    (car lst)
  )
)

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Reverse a string of text
« Reply #12 on: February 01, 2011, 03:52:05 PM »
Just noticed, you don't want the string reversed, but the alpha/numerical parts switched... forget all my posts in this thread...  :ugly:

alanjt

  • Needs a day job
  • Posts: 5352
  • Standby for witty remark...
Re: Reverse a string of text
« Reply #13 on: February 01, 2011, 03:59:43 PM »
I wrote this as a quick change up to Lee's, but I just noticed his realization and I too am posting crap.

Code: [Select]
(defun ReverseTag (string)
  (vl-list->string
    (cdr (apply (function append)
                (mapcar
                  (function
                    (lambda (x)
                      (cons 32
                            (if (wcmatch x "*#")
                              (reverse (vl-string->list x))
                              (vl-string->list x)
                            )
                      )
                    )
                  )
                  (LM:str->lst string " ")
                )
         )
    )
  )
)
Civil 3D 2019 ~ Windohz 7 64bit
Dropbox

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Reverse a string of text
« Reply #14 on: February 01, 2011, 04:21:22 PM »
I think RegularExpressions are the way to go with this one:

Code: [Select]
(defun ReverseTag ( regex string )
  (mapcar
    (function
      (lambda ( x ) (vlax-put-property regex (car x) (cdr x)))
    )
    (list
      (cons 'global      acfalse)
      (cons 'ignorecase  actrue)
      (cons 'multiline   acfalse)
      (cons 'pattern     "([A-Z]+)(\\d+)\\b")
    )
  )
  (vlax-invoke regex 'replace string "$2$1")
)

Test function:

Code: [Select]
(defun c:test ( / RegEx string ) (vl-load-com)

  (setq string "FUSE A7 2A 24VDC")

  (setq RegEx  (vlax-get-or-create-object "VBScript.RegExp"))
  (setq string (ReverseTag RegEx string))
  (vlax-release-object RegEx)

  string
)

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Reverse a string of text
« Reply #15 on: February 01, 2011, 07:37:07 PM »
Very slick Lee. 8-)

This is the long way. :-)
Code: [Select]
(defun c:numFirst (/ ss i ename txt str elst nlst nstr)
  ;;  parser by CAB  
  (defun sparser (str delim / ptr lst)
    (while (setq ptr (vl-string-search delim str))
      (setq lst (cons (substr str 1 ptr) lst))
      (setq str (substr str (+ ptr 2)))
    )
    (reverse (cons str lst))
  )

  (defun chkStr (s / num str)
    (if (wcmatch s "*#")
      (progn
        (mapcar
          (function
            (lambda (x)
              (if (< 47 x 58)
                (setq num (cons x num))
                (setq str (cons x str))
              )
            )
          )
          (reverse (vl-string->list S))
        )
        (vl-list->string (if str (append num str) num))
      )
      s
    )
  )

  (if (setq ss (ssget "_:L" '((0 . "TEXT"))))
    (progn
      (setq i -1)
      (while (setq ename (ssname ss (setq i (1+ i))))
        (setq nstr nil
              nlst nil)
        (setq txt (cdr (assoc 1 (setq elst (entget ename)))))
        (foreach str (setq lst (sparser txt " "))
          (setq str (chkStr str))
          (setq nlst (cons str nlst))
        )
        (mapcar (function (lambda(s) (setq nstr (if nstr (strcat nstr " " s) s)))) (reverse nlst))
        (if nstr (entmod (subst (cons 1 nstr) (assoc 1 elst) elst)))
      )
    )
  )

  (princ)
)

edit: Added "_:L" to my ssget, thanks for the reminder Lee
« Last Edit: February 02, 2011, 08:13:20 AM by CAB »
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Reverse a string of text
« Reply #16 on: February 01, 2011, 07:57:23 PM »
Thanks Alan, nice code also  :-)

I should probably include a more appropriate calling function for mine:

Code: [Select]
(defun c:test ( / RegEx ss i str elist ) (vl-load-com)

  (setq RegEx  (vlax-get-or-create-object "VBScript.RegExp"))

  (mapcar
    (function
      (lambda ( x ) (vlax-put-property regex (car x) (cdr x)))
    )
    (list
      (cons 'global      acfalse)
      (cons 'ignorecase  actrue)
      (cons 'multiline   acfalse)
      (cons 'pattern     "([A-Z]+)(\\d+)\\b")
    )
  )

  (if (setq ss (ssget "_:L" '((0 . "TEXT") (1 . "*@#*"))))
   
    (repeat (setq i (sslength ss))
      (setq str (cdr (assoc 1 (setq elist (entget (ssname ss (setq i (1- i))))))))

      (if (not (eq str (setq str (vlax-invoke regex 'replace str "$2$1"))))
        (entupd (cdr (assoc -1 (entmod (subst (cons 1 str) (assoc 1 elist) elist)))))
      )
    )
  )

  (vlax-release-object RegEx)
  (princ)
)

EDIT: In fact, I think it'd be more efficient without the sub :-)

ElpanovEvgeniy

  • Water Moccasin
  • Posts: 1569
  • Moscow (Russia)
Re: Reverse a string of text
« Reply #17 on: February 02, 2011, 05:55:02 AM »
my variant, not use vla:
Code: [Select]
(defun f (l)
 (cond ((= (caddr l) "") (strcat (cadr l) (car l)))
       ((wcmatch (caddr l) "@*") (f (list (strcat (car l) (substr (caddr l) 1 1)) (cadr l) (substr (caddr l) 2))))
       ((wcmatch (caddr l) "#*") (f (list (car l) (strcat (cadr l) (substr (caddr l) 1 1)) (substr (caddr l) 2))))
       ((strcat (cadr l) (car l) " " (f (list "" "" (substr (caddr l) 2)))))
 )
)

Test function:
Code: [Select]
(defun c:test (/ s)
 (setq s "FUSE A7 2A 24VDC")
 (f (list "" "" s))
)

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Reverse a string of text
« Reply #18 on: February 02, 2011, 08:04:02 AM »
Evgeniy,

Nice idea to separate the alpha/numerical sections into separate elements of the list (I wouldn't have thought to approach it in that way...) - I should imagine you lose performance however with the recursion combined with the inefficient strcat/substr functions...

The trace call is quite elegant:

Code: [Select]
Entering (F ("" "" "FUSE A7 2A 24VDC"))
  Entering (F ("F" "" "USE A7 2A 24VDC"))
    Entering (F ("FU" "" "SE A7 2A 24VDC"))
      Entering (F ("FUS" "" "E A7 2A 24VDC"))
        Entering (F ("FUSE" "" " A7 2A 24VDC"))
          Entering (F ("" "" "A7 2A 24VDC"))
            Entering (F ("A" "" "7 2A 24VDC"))
              Entering (F ("A" "7" " 2A 24VDC"))
                Entering (F ("" "" "2A 24VDC"))
                  Entering (F ("" "2" "A 24VDC"))
                    Entering (F ("A" "2" " 24VDC"))
                      Entering (F ("" "" "24VDC"))
                        Entering (F ("" "2" "4VDC"))
                          Entering (F ("" "24" "VDC"))
                            Entering (F ("V" "24" "DC"))
                              Entering (F ("VD" "24" "C"))
                                Entering (F ("VDC" "24" ""))
                                Result:  "24VDC"
                              Result:  "24VDC"
                            Result:  "24VDC"
                          Result:  "24VDC"
                        Result:  "24VDC"
                      Result:  "24VDC"
                    Result:  "2A 24VDC"
                  Result:  "2A 24VDC"
                Result:  "2A 24VDC"
              Result:  "7A 2A 24VDC"
            Result:  "7A 2A 24VDC"
          Result:  "7A 2A 24VDC"
        Result:  "FUSE 7A 2A 24VDC"
      Result:  "FUSE 7A 2A 24VDC"
    Result:  "FUSE 7A 2A 24VDC"
  Result:  "FUSE 7A 2A 24VDC"
Result:  "FUSE 7A 2A 24VDC"

However, you will have a problem with:

Code: [Select]
(setq s "FUSE A10A")
A possible fix might be:

Code: [Select]
(defun f ( l )
  (cond
    ( (= (caddr l) "")

      (strcat (cadr l) (car l))
    )
    ( (and (< 0 (strlen (cadr l))) (wcmatch (caddr l) "@*"))

      (f (list (strcat (car l) (cadr l) (substr (caddr l) 1 1)) "" (substr (caddr l) 2)))
    )
    ( (wcmatch (caddr l) "@*")

      (f (list (strcat (car l) (substr (caddr l) 1 1)) (cadr l) (substr (caddr l) 2)))
    )
    ( (wcmatch (caddr l) "#*")

      (f (list (car l) (strcat (cadr l) (substr (caddr l) 1 1)) (substr (caddr l) 2)))
    )
    ( (strcat (cadr l) (car l) " " (f (list "" "" (substr (caddr l) 2))))
    )
  )
)

:-)
« Last Edit: February 02, 2011, 08:07:32 AM by Lee Mac »

ElpanovEvgeniy

  • Water Moccasin
  • Posts: 1569
  • Moscow (Russia)
Re: Reverse a string of text
« Reply #19 on: February 02, 2011, 08:24:46 AM »
Thanks Lee!  :-)
Thanks for the correction.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Reverse a string of text
« Reply #20 on: February 02, 2011, 09:04:07 AM »
Mine would choke on this FUSE F10-A30 -> FUSE F10-30A

But that was not in the requirements.  :evil:
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Reverse a string of text
« Reply #21 on: February 02, 2011, 09:17:44 AM »
This might be a better pattern to match:

Code: [Select]
(defun c:test ( / RegEx ss i str elist ) (vl-load-com)

  (setq RegEx  (vlax-get-or-create-object "VBScript.RegExp"))

  (mapcar
    (function
      (lambda ( x ) (vlax-put-property regex (car x) (cdr x)))
    )
    (list
      (cons 'global      actrue)
      (cons 'ignorecase  actrue)
      (cons 'multiline   acfalse)
      (cons 'pattern     "([A-Z]+)(\\d+)(\\s|$)")
    )
  )

  (if (setq ss (ssget "_:L" '((0 . "TEXT") (1 . "*@#*"))))
   
    (repeat (setq i (sslength ss))
      (setq str (cdr (assoc 1 (setq elist (entget (ssname ss (setq i (1- i))))))))

      (if (not (eq str (setq str (vlax-invoke regex 'replace str "$2$1$3"))))
        (entupd (cdr (assoc -1 (entmod (subst (cons 1 str) (assoc 1 elist) elist)))))
      )
    )
  )

  (vlax-release-object RegEx)
  (princ)
)

Note sure if the 'global' property is required or not, but that is an easy switch in the code.

Code: [Select]
FUSE A2 A10A F10-A30  -->  FUSE 2A A10A F10-30A

FUSE A12 1A 12VDC     -->  FUSE 12A 1A 12VDC

ElpanovEvgeniy

  • Water Moccasin
  • Posts: 1569
  • Moscow (Russia)
Re: Reverse a string of text
« Reply #22 on: February 02, 2011, 09:55:56 AM »
Very controversial mechanism:
Code: [Select]
"FUSE A2 A10A A10-A30" -->> "FUSE 2A A10A A10-30A"

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Reverse a string of text
« Reply #23 on: February 02, 2011, 09:58:18 AM »
Very controversial mechanism:
Code: [Select]
"FUSE A2 A10A A10-A30" -->> "FUSE 2A A10A A10-30A"

True, it wasn't in the OP's requirements, but we like to go the extra mile  ;-)

ElpanovEvgeniy

  • Water Moccasin
  • Posts: 1569
  • Moscow (Russia)
Re: Reverse a string of text
« Reply #24 on: February 02, 2011, 10:03:23 AM »
my variant 2:
Code: [Select]
(defun f (l)
 (cond ((= (caddr l) "") (strcat (cadr l) (car l)))
       ((wcmatch (caddr l) "@*") (f (list (strcat (car l) (cadr l) (substr (caddr l) 1 1)) "" (substr (caddr l) 2))))
       ((wcmatch (caddr l) "#*") (f (list (car l) (strcat (cadr l) (substr (caddr l) 1 1)) (substr (caddr l) 2))))
       ((strcat (cadr l) (car l) (substr (caddr l) 1 1) (f (list "" "" (substr (caddr l) 2)))))
 )
)

Code: [Select]
(f '("""""FUSE A2 A10A F10-A30")) ;;  -->  "FUSE 2A A10A 10F-30A"
:)