Sunday, June 13, 2021

#1 2021-05-03 12:03:32 pm

NewtonsLaws
Member
From:: Switzerland
Registered: 2021-05-02
Posts: 14

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:

Applescript:

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!

Offline

 

#2 2021-05-03 01:21:57 pm

KniazidisR
Member
From:: Greece
Registered: 2019-03-03
Posts: 1878

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

Hi,

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

Applescript:


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

Last edited by KniazidisR (2021-05-03 02:17:23 pm)


Model: MacBook Pro
OS X: Catalina 10.15.4
Web Browser: Safari 14.1
Ram: 4 GB

Offline

 

#3 2021-05-03 02:09:20 pm

NewtonsLaws
Member
From:: Switzerland
Registered: 2021-05-02
Posts: 14

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

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.

Last edited by NewtonsLaws (2021-05-03 02:20:00 pm)

Offline

 

#4 2021-05-03 02:18:40 pm

KniazidisR
Member
From:: Greece
Registered: 2019-03-03
Posts: 1878

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

Now my script above returns Bruce, without Li. big_smile


Model: MacBook Pro
OS X: Catalina 10.15.4
Web Browser: Safari 14.1
Ram: 4 GB

Offline

 

#5 2021-05-03 02:21:51 pm

NewtonsLaws
Member
From:: Switzerland
Registered: 2021-05-02
Posts: 14

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

Yeah big_smile thanks for that! You helped me a lot.

Offline

 

#6 2021-05-03 02:24:56 pm

KniazidisR
Member
From:: Greece
Registered: 2019-03-03
Posts: 1878

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

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

Applescript:


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

Last edited by KniazidisR (2021-05-03 02:28:20 pm)


Model: MacBook Pro
OS X: Catalina 10.15.4
Web Browser: Safari 14.1
Ram: 4 GB

Offline

 

#7 2021-05-03 08:09:21 pm

peavine
Member
From:: Prescott, Arizona
Registered: 2018-09-04
Posts: 910

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

NewtonsLaws wrote:

"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



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.

Applescript:

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

Last edited by peavine (2021-05-03 10:14:28 pm)


2018 Mac mini - macOS Catalina

Offline

 

#8 2021-05-04 12:09:21 am

Fredrik71
Member
Registered: 2019-10-23
Posts: 798

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

Here is other approach that use ASObjC NSDataDetector Class
This example only return the first item it finds. Since your example use the same it doesn't matter.

Applescript:

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

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

-- To filter to only return the first item, could be changed.
set theString to (item 1 of (my textCheckingForLink:(txt as text)))'s second word

set ASTID to AppleScript's text item delimiters
set AppleScript's text item delimiters to "."
set textItems to every text item of ((current application's NSString's stringWithString:(theString))'s capitalizedString() as text)
set AppleScript's text item delimiters to ASTID

set {theFirstname, theLastname} to {item 1 of textItems, item 2 of textItems}
return {FirstName:theFirstname, LastName:theLastname} as record

on textCheckingForLink:theText
   set theString to current application's NSString's stringWithString:theText
   set dataDetector to current application's NSDataDetector's dataDetectorWithTypes:(current application's NSTextCheckingTypeLink as integer) |error|:(missing value)
   set arrayMatches to dataDetector's matchesInString:theString options:0 range:(current application's NSMakeRange(0, theString's |length|()))
   -- NSLinkCheckingResult:
   return (arrayMatches's valueForKeyPath:"URL.absoluteString") as list
end textCheckingForLink:

Last edited by Fredrik71 (2021-05-04 12:55:28 am)


if you are the expert, who will you call if its not your imagination.

Online

 

#9 2021-05-04 01:28:41 am

NewtonsLaws
Member
From:: Switzerland
Registered: 2021-05-02
Posts: 14

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

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

Offline

 

#10 2021-05-04 03:32:45 am

Fredrik71
Member
Registered: 2019-10-23
Posts: 798

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

This maybe is not the best approach but it works.

Lets say you have a list of string and you like to get the name from email address from the strings.

Applescript:

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

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

my namesFromString:(theList as text) delimiter:"."
on namesFromString:theItems delimiter:theDelimiter
   set theStringList to {}
   set theDetector to my textCheckingForLink:(theItems)
   repeat with anItem in theDetector
       set anItem to (current application's NSString's stringWithString:(anItem))'s capitalizedString() as text
       set the end of theStringList to anItem's second word
   end repeat
   
   set ASTID to AppleScript's text item delimiters
   set AppleScript's text item delimiters to ","
   set textItems to every text item of theStringList
   set AppleScript's text item delimiters to theDelimiter
   set theStringList to {}
   repeat with anItem in textItems
       set the end of theStringList to (every text item of anItem)
   end repeat
   set AppleScript's text item delimiters to ASTID
   
   return theStringList
end namesFromString:delimiter:

on textCheckingForLink:theText
   set theString to current application's NSString's stringWithString:theText
   set dataDetector to current application's NSDataDetector's dataDetectorWithTypes:(current application's NSTextCheckingTypeLink as integer) |error|:(missing value)
   set arrayMatches to dataDetector's matchesInString:theString options:0 range:(current application's NSMakeRange(0, theString's |length|()))
   -- NSLinkCheckingResult:
   return (arrayMatches's valueForKeyPath:"URL.absoluteString") as list
end textCheckingForLink:

And if we like to have first name and last name in same string.
We could change the handler namesFromString:delimiter: to the code below.

Applescript:

on namesFromString:theItems delimiter:theDelimiter
   set theStringList to {}
   set theDetector to my textCheckingForLink:(theItems)
   repeat with anItem in theDetector
       set anItem to (current application's NSString's stringWithString:(anItem))'s capitalizedString() as text
       set the end of theStringList to anItem's second word
   end repeat
   
   set ASTID to AppleScript's text item delimiters
   set AppleScript's text item delimiters to ","
   set theItemList to every text item of theStringList
   set AppleScript's text item delimiters to theDelimiter
   set theStringList to {}
   repeat with anItem in theItemList
       set theItem to text items 1 thru 2 of anItem
       set the end of theStringList to (item 1 of theItem & space & item 2 of theItem)
   end repeat
   set AppleScript's text item delimiters to ASTID
   return theStringList
end namesFromString:delimiter:

And if we like to have a record of names and emails, and this could properly been done much faster.

Applescript:

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

set theList to {"Natalia ferrara 077559 020 8946 66003 bruce.wayne@wayneindustries.com", "Fan Boy bill.gates@wayneindustries.uk 077559 020 8946 66003 byrens ", "One more thing...steve.jobs@apple.com"}

set theResult to {}
repeat with anItem in theList
   set the end of theResult to (my emailsAndNamesFromString:anItem delimiter:".")
end repeat
-- Return theResult
return theResult

on emailsAndNamesFromString:theItems delimiter:theDelimiter
   set {theStringList, theEmailList} to {{}, {}}
   set theDetector to my textCheckingForLink:(theItems)
   repeat with anItem in theDetector
       set the end of theEmailList to word 2 of anItem & "@" & word 3 of anItem
       set anItem to (current application's NSString's stringWithString:(anItem))'s capitalizedString() as text
       set the end of theStringList to anItem's second word
   end repeat
   
   set ASTID to AppleScript's text item delimiters
   set AppleScript's text item delimiters to ","
   set textItems to every text item of theStringList
   set AppleScript's text item delimiters to theDelimiter
   set theStringList to {}
   repeat with anItem in textItems
       set theItem to text items 1 thru 2 of anItem
       set the end of theStringList to (item 1 of theItem & space & item 2 of theItem)
   end repeat
   set AppleScript's text item delimiters to ASTID
   return {name:theStringList, email:theEmailList}
end emailsAndNamesFromString:delimiter:

on textCheckingForLink:theText
   set theString to current application's NSString's stringWithString:theText
   set dataDetector to current application's NSDataDetector's dataDetectorWithTypes:(current application's NSTextCheckingTypeLink as integer) |error|:(missing value)
   set arrayMatches to dataDetector's matchesInString:theString options:0 range:(current application's NSMakeRange(0, theString's |length|()))
   -- NSLinkCheckingResult:
   return (arrayMatches's valueForKeyPath:"URL.absoluteString") as list
end textCheckingForLink:

Last edited by Fredrik71 (2021-05-04 12:46:09 pm)


if you are the expert, who will you call if its not your imagination.

Online

 

#11 2021-05-04 01:33:09 pm

wch1zpink
Member
Registered: 2011-08-20
Posts: 25

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

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

Applescript:

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

Offline

 

#12 2021-05-05 06:28:19 am

NewtonsLaws
Member
From:: Switzerland
Registered: 2021-05-02
Posts: 14

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

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):

Applescript:



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.

Last edited by NewtonsLaws (2021-05-05 11:24:22 am)

Offline

 

#13 2021-05-05 10:30:22 am

KniazidisR
Member
From:: Greece
Registered: 2019-03-03
Posts: 1878

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

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

and this:

Applescript:

set emails to {theToRecipient}

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

Applescript:

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.

Last edited by KniazidisR (2021-05-05 11:04:24 am)


Model: MacBook Pro
OS X: Catalina 10.15.4
Web Browser: Safari 14.1
Ram: 4 GB

Offline

 

#14 2021-05-05 11:39:34 am

NewtonsLaws
Member
From:: Switzerland
Registered: 2021-05-02
Posts: 14

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

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

Last edited by NewtonsLaws (2021-05-06 09:16:28 am)

Offline

 

#15 2021-05-07 04:00:28 am

NewtonsLaws
Member
From:: Switzerland
Registered: 2021-05-02
Posts: 14

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

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.

Applescript:

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

Last edited by NewtonsLaws (2021-05-07 11:01:18 am)

Offline

 

#16 2021-05-08 01:45:15 pm

NewtonsLaws
Member
From:: Switzerland
Registered: 2021-05-02
Posts: 14

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

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 smile

This works and extracts the first name:

Applescript:

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

Offline

 

Board footer

Powered by FluxBB

RSS (new topics) RSS (active topics)