Jump to content

Replace parts of strings using wildcards


Ament

Recommended Posts

Hi together,

 

I'm breaking my head about a hopefully simple task.

Let's start from the beginning. I'm trying to remove attributes like widthfactor, tracking and angle from a MTEXT. Unfortunately these can't be done as simple as for single line text. The attribute values are part of the string.

With a few modifications just for testing the string ("TestString") looks like this:

(1 . "{\\Q10;\\T0.75;Test\\Q0;\\W0.8;\\T0.9;String}")

After removing all attributes the string should become like this:

(1 . "TestString")

If the widthfactor would be constant (\\T0.75;) it would be simple to write, but as it can vary and also be included between two parts of the final string I have to use wildcards to identify the correct part of the string. My plan is to replace the parts of the string with a just two quotationmarks. First I tried to find a good syntax to check if these kind of attributes are included.

I use wcmatch for that:

(wcmatch TMPSTR "*\\T[0-9]*[`.][0-9]*;*")

But when I try to substitute the part with the following command it doesn't work for me :(

(vl-string-subst "" "*\\T[0-9]*[`.][0-9]*;*" TMPSTR)

To me it looks like it doesn't take into account the wildcards.

 

I may be wrong and would gladly appreciate any hint or solution how I can strip my imput string.

 

Best regards,

Ament

Link to comment
Share on other sites

Thanks @ronjonp 👍

 

The function used in this example program (and based on my Unformat String function) is more efficient for repeated evaluation as the RegEx object is supplied as an argument, rather than created/released by the function:

;; Quick Unformat  -  Lee Mac
;; Returns a string with all MText formatting codes removed.
;; rgx - [vla] Regular Expressions (RegExp) Object
;; str - [str] String to process

(defun LM:quickunformat ( rgx str )
    (if
        (null
            (vl-catch-all-error-p
                (setq str
                    (vl-catch-all-apply
                       '(lambda nil
                            (vlax-put-property rgx 'global     actrue)
                            (vlax-put-property rgx 'multiline  actrue)
                            (vlax-put-property rgx 'ignorecase acfalse) 
                            (foreach pair
                               '(
                                    ("\032"     . "\\\\\\\\")
                                    (" "        . "\\\\P|\\n|\\t")
                                    ("$1"       . "\\\\(\\\\[ACcFfHKkLlOopQTW])|\\\\[ACcFfHKkLlOopQTW][^\\\\;]*;|\\\\[ACcFfKkHLlOopQTW]")
                                    ("$1$2/$3"  . "([^\\\\])\\\\S([^;]*)[/#\\^]([^;]*);")
                                    ("$1$2"     . "\\\\(\\\\S)|[\\\\](})|}")
                                    ("$1"       . "[\\\\]({)|{")
                                    ("\\$1$2$3" . "(\\\\[ACcFfHKkLlOoPpQSTW])|({)|(})")
                                    ("\\\\"     . "\032")
                                )
                                (vlax-put-property rgx 'pattern (cdr pair))
                                (setq str (vlax-invoke rgx 'replace str (car pair)))
                            )
                        )
                    )
                )
            )
        )
        str
    )
)

An example function to test:

(defun test ( str / reg )
    (if (setq reg (vlax-create-object "vbscript.regexp"))
        (progn
            (setq str (LM:quickunformat reg str))
            (vlax-release-object reg)
            str
        )
    )
)

Used with the OP's example:

_$ (test "{\\Q10;\\T0.75;Test\\Q0;\\W0.8;\\T0.9;String}")
"TestString"

 

Edited by Lee Mac
Link to comment
Share on other sites

Lee, just sharing a personal preference: 

Rather than requiring the caller to pass a RegEx object I think its better to require a list of strings argument, so the iteration will perform inside the subfunciton.

i'm saying it, because not everyone is aware how to create RegEx object+knowing that he have to release it (for instance - the OP).

Link to comment
Share on other sites

1 hour ago, Grrr said:

Rather than requiring the caller to pass a RegEx object I think its better to require a list of strings argument, so the iteration will perform inside the subfunciton.

i'm saying it, because not everyone is aware how to create RegEx object+knowing that he have to release it (for instance - the OP).

 

Then the caller should do some reading before using the function 😉

Link to comment
Share on other sites

2 hours ago, Lee Mac said:

 

Then the caller should do some reading before using the function 😉

 

Lee, rethinking now.. its fair enough that the caller could use or write a wrapper function, like the example you provided. 👍

Its just my style that keeps the execution context within the one certain subfunction

(meaning its like just invoking a method and getting something returned, without additional requirements).

Link to comment
Share on other sites

7 hours ago, Lee Mac said:

 

Then the caller should do some reading before using the function 😉

Totally agree. The amount of detail you provide to use your code takes you out of equation. 🍻

Link to comment
Share on other sites

Thanks everyone for the help.

I'll try this one later. From first sight I guess Lee Mac is right, I should read a bit before using it, but the hints in here are hopefully enough to guide me to the correct path ;)

I'll update you if i succeded or need further adivces :D

Link to comment
Share on other sites

Looks really good. It's integrated in my code and is working well. Thanks a lot everyone and especially @Lee Mac.

Oftenly when I try to solve an issue in here I find either a routine or some pieces of them in the coding you did  already! You can't imagine how much I appreciate your work and that you allow to use it.

Thank you!

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...