Extract first part of email (first name) out of a string

Hi all I hope you guys are well,

A problem I am facing is how to extract the first part of an email, which is the first name, from a longer string. The following is what I mean:

“Wayne Industries, bruce.wayne@wayneindustries.org, Away” → return “Bruce”

While searching in the forum (I am new here) I have come across a very remarkable 14 year old script from Marc hunte (he rocks!), that still works well and almost brings me there until one problem stated after this.

The brilliant script goes as follows:

set txt to {"Natalia ferrara 077559 020 8946 66003 bruce.wayne@wayneindustries.or", "Fan Boy bruce.wayne@wayneindustries.or 077559 020 8946 66003 byrens "}
set AddressList to {}
repeat with i from 1 to number of items in txt
   set AppleScript's text item delimiters to {"@"} --sets new dilm
   set this_txt to item i of txt
   set right_txt to word 1 of text item -1 of this_txt
   set left_txt to word -1 of text item 1 of this_txt
   set AppleScript's text item delimiters to "" -- resets dilm
   copy left_txt & "@" & right_txt as string to end of AddressList
end repeat

return item 1 of AddressList

But HOW do I get now the FIRST PART of that e-mail out of strings like that:

“Bruce Wayne, bruce.wayne@wayneindustries.org, Away” → return “Bruce”
bruce.wayne@wayneindustries.org, Away” → return “Bruce”
“Industries, bruce.wayne@wayneindustries.org, Here” → return “Bruce”

if there is no “.” then → “Industries, wayne@wayneindustries.org, Here” → return “Wayne”

What i wish the script would be structured, would be more or less like this:

1) check if there is an “@” in the string.
2) take the word left to the “@”, the first part of the email address → “bruce.wayne” or “wayne”
3) IF there is a “.” take the first name if not the the full name → “bruce”
4) Make the first letter a capital → “Bruce”
5) return “Bruce” as a variable

I’m not sure how to get there, since this is way over my head. Any help from you pros with this would be much appreciated.

Best wishes and many thanks for your help in this!

Hi,

You should firstly get part of text (word) which contains “@”, then you should cut right side of this word. Like this:


use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

set emails to {"Natalia ferrara 077559 020 8946 66003 brucewayne@wayneindustries.or", "Fan Boy bruce.wayne@wayneindustries.or 077559 020 8946 66003 byrens "}

set AddressList to {}
repeat with email in emails
	set AppleScript's text item delimiters to space
	set theWords to text items of email -- split to the parts firsly, criteria - space
	set AppleScript's text item delimiters to ""
	repeat with aWord in theWords
		if aWord contains "@" then -- find part, which contains "@"
			set AppleScript's text item delimiters to "@"
			set left_txt to first text item of aWord -- get part of finded part on left of "@"
			set AppleScript's text item delimiters to "."
			set left_txt to text items of left_txt -- try to split parts of name
			set AppleScript's text item delimiters to " "
			set theName to text item 1 of left_txt -- get short name
			set AppleScript's text item delimiters to ""
			-- convert to NSString
			set theName to (current application's NSString's stringWithString:theName)
			-- add capitalized text to AddressList
			copy (theName's capitalizedString() as text) to end of AddressList
			exit repeat
		end if
	end repeat
end repeat

return item 1 of AddressList

Hi KniazidisR

So far, I have already learned so much from your response, thank you!

At the moment your script (return item 1 of AddressList) returns “Bruce Wayne”. The goal of the script would be to just return “Bruce”. Would you be so kind to show me how to get there as well, that would be amazing.

Edit: SORRY of course this does the trick: return word 1 of item 1 of AddressList Well, I’m new to this but case closed. Thanks!

Best wishes and many thanks for your kind help.

Now my script above returns Bruce, without Li. :smiley:

Yeah :smiley: thanks for that! You helped me a lot.

This is last revision (I removed one redundant step.)


use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

set emails to {"Natalia ferrara 077559 020 8946 66003 bruce.wayne@wayneindustries.or", "Fan Boy bruce.wayne@wayneindustries.or 077559 020 8946 66003 byrens "}

set AddressList to {}
repeat with email in emails
	set AppleScript's text item delimiters to space
	set theWords to text items of email -- split to the parts firsly, criteria - space
	set AppleScript's text item delimiters to ""
	repeat with aWord in theWords
		if aWord contains "@" then -- find part, which contains "@"
			set AppleScript's text item delimiters to "@"
			set left_txt to first text item of aWord -- get part of finded part on left of "@"
			set AppleScript's text item delimiters to "."
			set theName to text item 1 of left_txt -- try to split parts of name (get first name)
			set AppleScript's text item delimiters to ""
			-- convert to NSString
			set theName to (current application's NSString's stringWithString:theName)
			-- add capitalized text to AddressList
			copy (theName's capitalizedString() as text) to end of AddressList
			exit repeat
		end if
	end repeat
end repeat

return item 1 of AddressList

KniazidisR has already answered the OP’s question. However, my current topic of study of ASObjC is delimiting text, and I decided to use the OP’s request as practice. I’m posting the script here just FWIW.

use framework "Foundation"
use scripting additions

on getTheName(theString)
	set theString to current application's NSString's stringWithString:theString
	set theString to item 1 of (theString's componentsSeparatedByString:"@")
	set theString to item -1 of (theString's componentsSeparatedByString:" ")
	if (theString as text) contains "." then
		set theArray to (theString's componentsSeparatedByString:".")
		return (item -2 of theArray)'s capitalizedString() as text
	else
		return theString's capitalizedString() as text
	end if
end getTheName

getTheName("Bruce Wayne, bruce.wayne@wayneindustries.org, Away") --> Bruce
getTheName("bruce.wayne@wayneindustries.org, Away") --> Bruce
getTheName("Industries, bruce.wayne@wayneindustries.org, Here") --> Bruce
getTheName("Industries, wayne@wayneindustries.org, Here") --> Wayne

Thanks to everyone! The forum is wonderful and I am thankful for everyone’s help.

This following AppleScript code uses a completely different approach without the need for the use of text item delimiters.

use framework "Foundation"
use scripting additions
property NSString : a reference to current application's NSString

property email1 : "bruce.wayne@wayneindustries.org, Away"
property email2 : "Industries, bruce.wayne@wayneindustries.org, Here"
property email3 : "Bruce Wayne, bruce.wayne@wayneindustries.org, Away"
property email4 : "Industries, wayne@wayneindustries.org, Here"
property namesFromAllEmails : {}

set theEmails to {email1, email2, email3, email4}

repeat with i from 1 to count of theEmails
	set thisEmail to item i of theEmails
	
	set theResult to last item of extractName(thisEmail) as text
	
	set capitalizedName to capitalizeText(theResult)
	
	set end of namesFromAllEmails to capitalizedName
end repeat

to extractName(someEmail)
	set |offsetOf@| to (offset of "@" in someEmail) - 1
	set theText to text 1 thru |offsetOf@| of someEmail
	set |offsetOf.| to (offset of "." in theText) - 1
	set theName to words of text 1 thru |offsetOf.| of theText
end extractName

to capitalizeText(theTextToCapitalize)
	((NSString's stringWithString:theTextToCapitalize)'s capitalizedString()) as text
end capitalizeText

Hi guys

Thank you for all the great feedback! While working with the results, I run into an other problem, when including the script from KniazidisR into a working UI-script.

  1. The UI script on its own works really well and extracts and returns the recipient out of the “TO: field” in a string of “Industries, bruce.wayne@wayneindustries.org, Here” of the Apple-Mail-App.I would really love to keep working within that UI script, since its perfect for many of my other use cases.

  2. KniazidisR script takes the recipient string and returns the first name: “Bruce”

The problem: It’s probably very obvious to many pros of you, but i can’t get around it. If I include the use framework “Foundation” it immediately causes the error Expected “else”, etc. but found “use”. Maybe my use might be wrong or I don’t have the right knowledge. But do you guys know how this can be combined so that it works?

Here the full script (Edited after Community-Input):



use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

-- UI Mail Script to extract recipient
tell application "System Events"
	tell process "Mail"
		tell text field "To:" of window 1
			get count of UI elements
			if result is 1 then
				set theToRecipient to (value of UI element 1)
				
				-- Script from KniazidisR to format the List and extract first name out of email
				set emails to theToRecipient as list
				set AddressList to {}
				
				repeat with email in emails
					set AppleScript's text item delimiters to space
					set theWords to text items of email -- split to the parts firsly, criteria - space
					set AppleScript's text item delimiters to ""
					repeat with aWord in theWords
						if aWord contains "@" then -- find part, which contains "@"
							set AppleScript's text item delimiters to "@"
							set left_txt to first text item of aWord -- get part of finded part on left of "@"
							set AppleScript's text item delimiters to "."
							set theName to text item 1 of left_txt -- try to split parts of name (get first name)
							set AppleScript's text item delimiters to ""
							-- convert to NSString
							set theName to (current application's NSString's stringWithString:theName)
							-- add capitalized text to AddressList
							copy (theName's capitalizedString() as text) to end of AddressList
							exit repeat
						end if
					end repeat
				end repeat
				
				return item 1 of AddressList
				
			end if
		end tell
	end tell
end tell


Thanks for your help, much appreciated.

USE statements should be on the top of script. Move them from tell block to the top.

and this:

set emails to {theToRecipient}

may cause problems. So, write this code line other way:

set emails to theToRecipient as list

Also, I don’t understand why do you want the text as list. And why do you want to get the to recipients from GUI, and not normal way.

Thanks again a lot for the input KniazidisR! All of what you say make a lot of sense of course.

To give the forum the most value I edited the above script with your inputs. Almost there! But now I still get the error:

Can’t make «class ocid» id «data optr00000000D09A9F0200600000» into type text.

In response to your further questions:

  1. I use the same script for Microsoft Outlook for Mac (check PM-Message for reference). There UI seems the only way to be to extract that email. So I use the same script here for Mail.

  2. When there are more than one recipient, the text as list seems useful. Here I only used one as an example.

I hope I could clarify. Best wishes

I identified the problem, but can’t solve it yet. The script works perfectly well and extracts the first name in the variable “theName” as it should. Yet there’s somehow a problem with the NSString-conversion or/and the capitalisation to let it run within the GUI-Script above.

-- convert to NSString
set theName to (current application's NSString's stringWithString:theName)
-- add capitalized text to AddressList
copy (theName's capitalizedString() as text) to end of AddressList

Is there an other way to do what happens within those two lines? I will try to find a solution myself and post it here if I find one - any help in it would be greatly appreciated.

It is done!

Thanks to KniazidisR idea and peavine’s function I finally found the solution that does the trick for me.

As the Mandalorian says: This is the way!

  1. I put the “problematic” code-lines (NSString-conversion and the capitalisation) within a function
  2. I addressed that function then with my so that it worked within the GUI script

Hope that helps other beginners out there :slight_smile:

This works and extracts the first name:

use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

-- Get that first name and make caps function from peavine and KniazidisR
on getTheName(theString)
	set theString to current application's NSString's stringWithString:theString
	set theString to item 1 of (theString's componentsSeparatedByString:"@")
	set theString to item -1 of (theString's componentsSeparatedByString:" ")
	if (theString as text) contains "." then
		set theArray to (theString's componentsSeparatedByString:".")
		return (item -2 of theArray)'s capitalizedString() as text
	else
		return theString's capitalizedString() as text
	end if
end getTheName

-- GUI Mail Script to extract recipient
tell application "System Events"
	tell process "Mail"
		tell text field "To:" of window 1
			get count of UI elements
			if result is 1 then
				set theToRecipient to (value of UI element 1)
				return my getTheName(theToRecipient)			
			end if
		end tell
	end tell
end tell

Case closed :cool: