ksperopoulos Posted November 22, 2013 Posted November 22, 2013 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? Quote
Lee Mac Posted November 22, 2013 Posted November 22, 2013 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)" Quote
ksperopoulos Posted November 22, 2013 Author Posted November 22, 2013 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? Quote
Lee Mac Posted November 22, 2013 Posted November 22, 2013 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 Quote
ksperopoulos Posted November 22, 2013 Author Posted November 22, 2013 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. Quote
Tharwat Posted November 22, 2013 Posted November 22, 2013 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))) ) Quote
Lee Mac Posted November 22, 2013 Posted November 22, 2013 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)" Quote
ksperopoulos Posted November 22, 2013 Author Posted November 22, 2013 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? Quote
Tharwat Posted November 22, 2013 Posted November 22, 2013 Note that: is equivalent to: (- (1+ b) a) Correct Quote
Lee Mac Posted November 22, 2013 Posted November 22, 2013 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. Quote
ksperopoulos Posted November 22, 2013 Author Posted November 22, 2013 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? Quote
Lee Mac Posted November 22, 2013 Posted November 22, 2013 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)" Quote
ksperopoulos Posted November 22, 2013 Author Posted November 22, 2013 Thank you Lee! Your time and patience in helping me is invaluable! Quote
Recommended Posts
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.