Parsing outlook email strings, need just angle bracket text smtp address

Viewed 74

I have a string

Casperfoo DataOps <casperf@domain .com>;Booya Support <iptsupport@domain .com>; Tripped Support <Tsupport@domain capital.com>; Smith, Joe: IB Reference Data (NYK) <joe.smith@domain .com>; Johnson, Walter: IB Reference Data (PUN) <walter.johnson@domain .com>;

and I'd expect this to work

cat  /tmp/foo | perl -nle 'print /\<(\w+)\>/'

but it does not. All I want is the string between the < and the >. I don't need the crappy outlook aliases - just the smtp addresses.

This is the expected output

casperf@domain.com 
iptsupport@domain.com 
Tsupport@domaincapital.com  
joe.smith@domain.com 
walter.johnson@domain.com
2 Answers

and I'd expect this to work

Then your expectations are wrong :-) Perhaps you'd get closer if you read the regex documentation (or the tutorial).

Some problems:

  1. You match with \w+. The escape sequence \w matches letters, numbers and the underscore. Email addresses contain other characters (for example, @) so this matches nothing. Let's replace \w+ with \S+ (to match all non-whitespace characters).
  2. That still doesn't work, as your email addresses all seem to contain a space (e.g. <casperf@domain .com>). Ok, so let's use <.+> instead to match anything, but add ? to force a minimal match - <.+?>.
  3. That just gives us the first match, because that's what we're asking for. We need to add /g to the match operator to get all matches.

We now have:

$ cat  /tmp/foo | perl -nle 'print /\<(.+?)\>/g

Which gives us:

casperf@domain .comiptsupport@domain .comTsupport@domain capital.comjoe.smith@domain .comwalter.johnson@domain .com

So we get all of the matches, but they're all on the same line. The easiest fix is to put the match in a postfix for loop so print() gets the matches one at a time:

$ cat  /tmp/foo | perl -nle 'print for /\<(.+?)\>/g'
casperf@domain .com
iptsupport@domain .com
Tsupport@domain capital.com
joe.smith@domain .com
walter.johnson@domain .com

Try this:

cat /tmp/foo | perl -nle 'while (/<([^>]+)>/g){ print $1; }'

It should work. Tried it with

echo "Casperfoo DataOps <casperf@domain .com>;Booya Support <iptsupport@domain .com>; Tripped Support <Tsupport@domain capital.com>; Smith, Joe: IB Reference Data (NYK) <joe.smith@domain .com>; Johnson, Walter: IB Reference Data (PUN) <walter.johnson@domain .com>;" | perl -nle 'while (/<([^>]+)>/g){ print $1; }'

which gave me:

casperf@domain .com
iptsupport@domain .com
Tsupport@domain capital.com
joe.smith@domain .com
walter.johnson@domain .com
Related