A simple question but I can't find the answer. I'm scanning a huge pile of mails and would like to get rid of anything between () in the email adresses since this normally contains just info that varies over time. As a delimiter I use the ; between the email addresses. So this is basically the only character not allowed between ().

tst = "James, Jekyll (The.nice.guy@gmails.com \n); Hannibal, Hyde (from@hell ...)"

Obviously this doesn't work.

StringReplace[tst, "(" ~~ __ ... ~~ ")" -> ""]

It only leaves me James, Jekyll

So I assume I need a pattern like "("~~Anything Except ";"~~")" but how?

StringReplace[tst,"(" ~~ (DigitCharacter|WordCharacter|WhitespaceCharacter|"@"|"!"|".") ... ~~ ")" -> ""]

Will work but then to be safe I would need to get all characters in the ( | | etc) construct at seams unefficient.

Any thougths?


Since you mention the delimiter ;, I assume you want to do two things: remove the parentheses and split the string up into separate names.

 StringSplit[StringReplace[tst, "(" ~~ Except[")"|";"] ... ~~ ")" -> ""], 

This uses another version of StringReplace similar to Mr. Wizard's but not using Shortest. The StringSplit is what uses ; to identify separate email names.

The StringTrim is only added here to remove white space.

From the fact that you accepted Mr.Wizard's answer I understand that you wish for the replacement to fail when there is a ; between the ( ...). I've "upgraded" my solution to satisfy this strange requirement.

  • $\begingroup$ that is a nice way to represent Shortest! $\endgroup$ – Lou Jun 18 '12 at 19:18
  • $\begingroup$ It is also more flexible than using shortest. $\endgroup$ – Jens Jun 18 '12 at 19:19
  • $\begingroup$ Yes it is a strange requirement. But I found a very limited use (2 out of 441 addresses) of the ; sign to denote an email address Like Me, To (strange@mail; blah blah). Perhaps I should just ignore these mail addresses but they do occur also in other mails so to correlate them.. Perhaps it's to far fetched.. Thx $\endgroup$ – Lou Jun 18 '12 at 19:34

This will do what you want (concerning your original problem, not involving ;):

StringReplace[tst, ShortestMatch["(" ~~ __  ~~ ")"] -> ""]

The default is LongestMatch, which is why you did not get the rest.

  • $\begingroup$ "As of Version 6.0, ShortestMatch has been superseded by the pattern object Shortest." :-) $\endgroup$ – Mr.Wizard Jun 18 '12 at 18:43
  • $\begingroup$ @Mr.Wizard Is this true for strings as well? $\endgroup$ – Leonid Shifrin Jun 18 '12 at 18:44
  • $\begingroup$ I'm fairly certain it is. Isn't that the new paradigm? $\endgroup$ – Mr.Wizard Jun 18 '12 at 18:47
  • $\begingroup$ @Mr.Wizard Somehow I always felt that ShortestMatch is for strings only, and works differently (and most likely much faster) than Shortest for patterns, because string patterns are generally much faster than Mathematica patterns when used in string-processing built-in functions. $\endgroup$ – Leonid Shifrin Jun 18 '12 at 18:57
  • $\begingroup$ I believe it is just internally overloaded; if used for strings it switches. I only performed one test but I'm not seeing an efficiency difference. $\endgroup$ – Mr.Wizard Jun 18 '12 at 19:18


StringReplace[tst, "(" ~~ Shortest@x__ ~~ ")" -> ""]

Edit: After some consideration I do need Shortest as Leonid indicates:

StringReplace[tst, Shortest["(" ~~ Except[";"] ... ~~ ")"] -> ""]
  • $\begingroup$ I would suspect that when I use a ; in between the brackets the result would be different but it isn't. $\endgroup$ – Lou Jun 18 '12 at 19:04
  • $\begingroup$ No it's fine.. took the wrong string to test on.. sigh.. Since your answer matches most closely the question I'll accept your answer. $\endgroup$ – Lou Jun 18 '12 at 19:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.