Jump to content

Remove Text Outside Parentheses/Brackets


Recommended Posts

Posted

I would like to remove everything from an object's text that is outside a set of parentheses or brackets. I am wondering what the best way is to approach this. I have thought about finding the position of the parentheses/brackets using vl-string-position and then somehow using vl-string-left/right-trim. Any suggestions on how a more experienced person would attack this?

Posted

Since LISP is built for lists, I would manipulate the list of ASCII codes, e.g.:

(defun trimtobrackets ( s )
   (if (wcmatch s "*(*)*")
       (vl-list->string (reverse (member 41 (reverse (member 40 (vl-string->list s))))))
   )
)

_$ (trimtobrackets "outside (inside) outside")
"(inside)"

Posted

I haven't used wcmatch yet in any of my coding. Thank you for the suggestion. I will look into that today.

 

I have noticed the use of reverse a few times on this forum. What is the benefit of reversing the list?

Posted
I have noticed the use of reverse a few times on this forum. What is the benefit of reversing the list?

 

The reversal of the list is necessary to obtain the correct section of the list when member is used ;)

Posted

Gotcha! Thank you. I didn't realize you had to work from the beginning of a list. I thought you could work from the end backwards or from the beginning forwards.

Posted

Another ...

 

(setq st "Abc (IN) 123 ")

(if (and (setq a (vl-string-search "(" st)) (setq b (vl-string-search ")" st))
        )
 (substr st (1+ a) (- (+ 2 b) (1+ a)))
)

Posted

Note that:

(- (+ 2 b) (1+ a))

is equivalent to:

(- (1+ b) a)

However, I would be inclined to use vl-string-position over vl-string-search:

(defun trimtobrackets ( s / a b )
   (if
       (and
           (wcmatch s "*(*)*")
           (setq a (vl-string-position 40 s))
           (setq b (vl-string-position 41 s nil t))
       )
       (substr s (1+ a) (- (1+ b) a))
   )
)

To account for these cases:

_$ (trimtobrackets "abc(123(def)456)ghi")
"(123(def)456)"

Posted

Lee - why do I need to use the wcmatch function? If I know what I am looking for in the text, it should be able to pull the information out without this right?

Posted
Lee - why do I need to use the wcmatch function? If I know what I am looking for in the text, it should be able to pull the information out without this right?

 

To ensure that the supplied string contains the bracket characters to be trimmed to, otherwise you would either receive unexpected results or an error, depending on the method used to trim the characters.

Posted

OK. Thanks. I want to take the returned list and then remove the brackets as well. I am using vl-remove to do this. When I try

(vl-remove 91 93)

it returns too many arguments. I tried grouping them in parentheses, but this did not work. Do I have to run vl-remove twice or is there a way to group both ascii codes and run the remove function once?

Posted
OK. Thanks. I want to take the returned list and then remove the brackets as well. I am using vl-remove to do this. When I try
(vl-remove 91 93)

it returns too many arguments. I tried grouping them in parentheses, but this did not work. Do I have to run vl-remove twice or is there a way to group both ascii codes and run the remove function once?

 

Using vl-remove you would need to iterate over the list a number of times equal to the number of distinct items you wish to remove, e.g.:

_$ (setq lst '(0 1 2 3 4 5 6 7 8 9))
(0 1 2 3 4 5 6 7 8 9)
_$ (vl-remove 3 (vl-remove 4 (vl-remove 5 lst)))
(0 1 2 6 7 8 9)

It is more efficient (especially for longer lists) to use vl-remove-if with a predicate function.

For example, for your code:

(defun doit ( s / l )
   (setq l (vl-string->list s))
   (if (wcmatch s "*(*)*")
       (setq l (reverse (member 41 (reverse (member 40 l)))))
   )
   (vl-list->string (vl-remove-if '(lambda ( x ) (or (= 91 x) (= 93 x))) l))
)

_$ (doit "ABC(123[456]789)DEF")
"(123456789)"

Posted

Thank you Lee! Your time and patience in helping me is invaluable!

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...